mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.boringcrypto] all: merge master into dev.boringcrypto
Signing-side signature algorithm selection moved to selectSignatureScheme, so add FIPS logic there. Change-Id: I827e7296d01ecfd36072e2139e74603ef42c6b24
This commit is contained in:
commit
62ce702c77
1843 changed files with 119566 additions and 93149 deletions
2
AUTHORS
2
AUTHORS
|
|
@ -47,7 +47,7 @@ Ahmy Yulrizka <yulrizka@gmail.com>
|
||||||
Aiden Scandella <ai@uber.com>
|
Aiden Scandella <ai@uber.com>
|
||||||
Ainar Garipov <gugl.zadolbal@gmail.com>
|
Ainar Garipov <gugl.zadolbal@gmail.com>
|
||||||
Aishraj Dahal <aishraj@users.noreply.github.com>
|
Aishraj Dahal <aishraj@users.noreply.github.com>
|
||||||
Akhil Indurti <contact@akhilindurti.com>
|
Akhil Indurti <aindurti@gmail.com>
|
||||||
Akihiro Suda <suda.kyoto@gmail.com>
|
Akihiro Suda <suda.kyoto@gmail.com>
|
||||||
Akshat Kumar <seed@mail.nanosouffle.net>
|
Akshat Kumar <seed@mail.nanosouffle.net>
|
||||||
Alan Shreve <alan@inconshreveable.com>
|
Alan Shreve <alan@inconshreveable.com>
|
||||||
|
|
|
||||||
35
CONTRIBUTORS
35
CONTRIBUTORS
|
|
@ -67,7 +67,7 @@ Ahsun Ahmed <ahmed.ahsun@gmail.com>
|
||||||
Aiden Scandella <ai@uber.com>
|
Aiden Scandella <ai@uber.com>
|
||||||
Ainar Garipov <gugl.zadolbal@gmail.com>
|
Ainar Garipov <gugl.zadolbal@gmail.com>
|
||||||
Aishraj Dahal <aishraj@users.noreply.github.com>
|
Aishraj Dahal <aishraj@users.noreply.github.com>
|
||||||
Akhil Indurti <contact@akhilindurti.com>
|
Akhil Indurti <aindurti@gmail.com>
|
||||||
Akihiro Suda <suda.kyoto@gmail.com>
|
Akihiro Suda <suda.kyoto@gmail.com>
|
||||||
Akshat Kumar <seed@mail.nanosouffle.net>
|
Akshat Kumar <seed@mail.nanosouffle.net>
|
||||||
Al Cutter <al@google.com>
|
Al Cutter <al@google.com>
|
||||||
|
|
@ -76,6 +76,7 @@ Alan Donovan <adonovan@google.com>
|
||||||
Alan Shreve <alan@inconshreveable.com>
|
Alan Shreve <alan@inconshreveable.com>
|
||||||
Albert Nigmatzianov <albertnigma@gmail.com>
|
Albert Nigmatzianov <albertnigma@gmail.com>
|
||||||
Albert Strasheim <fullung@gmail.com>
|
Albert Strasheim <fullung@gmail.com>
|
||||||
|
Albert Teoh <albert.teoh@gmail.com>
|
||||||
Albert Yu <yukinying@gmail.com>
|
Albert Yu <yukinying@gmail.com>
|
||||||
Alberto Bertogli <albertito@blitiri.com.ar>
|
Alberto Bertogli <albertito@blitiri.com.ar>
|
||||||
Alberto Donizetti <alb.donizetti@gmail.com>
|
Alberto Donizetti <alb.donizetti@gmail.com>
|
||||||
|
|
@ -140,6 +141,7 @@ Ali Rizvi-Santiago <arizvisa@gmail.com>
|
||||||
Aliaksandr Valialkin <valyala@gmail.com>
|
Aliaksandr Valialkin <valyala@gmail.com>
|
||||||
Alif Rachmawadi <subosito@gmail.com>
|
Alif Rachmawadi <subosito@gmail.com>
|
||||||
Allan Simon <allan.simon@supinfo.com>
|
Allan Simon <allan.simon@supinfo.com>
|
||||||
|
Allen Li <ayatane@google.com>
|
||||||
Alok Menghrajani <alok.menghrajani@gmail.com>
|
Alok Menghrajani <alok.menghrajani@gmail.com>
|
||||||
Aman Gupta <aman@tmm1.net>
|
Aman Gupta <aman@tmm1.net>
|
||||||
Amir Mohammad Saied <amir@gluegadget.com>
|
Amir Mohammad Saied <amir@gluegadget.com>
|
||||||
|
|
@ -147,6 +149,7 @@ Amr Mohammed <merodiro@gmail.com>
|
||||||
Amrut Joshi <amrut.joshi@gmail.com>
|
Amrut Joshi <amrut.joshi@gmail.com>
|
||||||
Anand K. Mistry <anand@mistry.ninja>
|
Anand K. Mistry <anand@mistry.ninja>
|
||||||
Anders Pearson <anders@columbia.edu>
|
Anders Pearson <anders@columbia.edu>
|
||||||
|
Anderson Queiroz <contato@andersonq.eti.br>
|
||||||
André Carvalho <asantostc@gmail.com>
|
André Carvalho <asantostc@gmail.com>
|
||||||
Andre Nathan <andrenth@gmail.com>
|
Andre Nathan <andrenth@gmail.com>
|
||||||
Andrea Nodari <andrea.nodari91@gmail.com>
|
Andrea Nodari <andrea.nodari91@gmail.com>
|
||||||
|
|
@ -182,6 +185,7 @@ Andrew Radev <andrey.radev@gmail.com>
|
||||||
Andrew Skiba <skibaa@gmail.com>
|
Andrew Skiba <skibaa@gmail.com>
|
||||||
Andrew Stribblehill <ads@wompom.org>
|
Andrew Stribblehill <ads@wompom.org>
|
||||||
Andrew Szeto <andrew@jabagawee.com>
|
Andrew Szeto <andrew@jabagawee.com>
|
||||||
|
Andrew Todd <andrew.todd@wework.com>
|
||||||
Andrew Werner <andrew@upthere.com> <awerner32@gmail.com>
|
Andrew Werner <andrew@upthere.com> <awerner32@gmail.com>
|
||||||
Andrew Wilkins <axwalk@gmail.com>
|
Andrew Wilkins <axwalk@gmail.com>
|
||||||
Andrew Williams <williams.andrew@gmail.com>
|
Andrew Williams <williams.andrew@gmail.com>
|
||||||
|
|
@ -235,6 +239,7 @@ Arnaud Ysmal <arnaud.ysmal@gmail.com>
|
||||||
Arne Hormann <arnehormann@gmail.com>
|
Arne Hormann <arnehormann@gmail.com>
|
||||||
Arnout Engelen <arnout@bzzt.net>
|
Arnout Engelen <arnout@bzzt.net>
|
||||||
Aron Nopanen <aron.nopanen@gmail.com>
|
Aron Nopanen <aron.nopanen@gmail.com>
|
||||||
|
Artem Kolin <artemkaxboy@gmail.com>
|
||||||
Arthur Fabre <arthur@arthurfabre.com>
|
Arthur Fabre <arthur@arthurfabre.com>
|
||||||
Arthur Khashaev <arthur@khashaev.ru>
|
Arthur Khashaev <arthur@khashaev.ru>
|
||||||
Artyom Pervukhin <artyom.pervukhin@gmail.com>
|
Artyom Pervukhin <artyom.pervukhin@gmail.com>
|
||||||
|
|
@ -284,6 +289,7 @@ Benny Siegert <bsiegert@gmail.com>
|
||||||
Benoit Sigoure <tsunanet@gmail.com>
|
Benoit Sigoure <tsunanet@gmail.com>
|
||||||
Berengar Lehr <Berengar.Lehr@gmx.de>
|
Berengar Lehr <Berengar.Lehr@gmx.de>
|
||||||
Berkant Ipek <41230766+0xbkt@users.noreply.github.com>
|
Berkant Ipek <41230766+0xbkt@users.noreply.github.com>
|
||||||
|
Bharath Thiruveedula <tbharath91@gmail.com>
|
||||||
Bill Neubauer <wcn@golang.org> <wcn@google.com> <bill.neubauer@gmail.com>
|
Bill Neubauer <wcn@golang.org> <wcn@google.com> <bill.neubauer@gmail.com>
|
||||||
Bill O'Farrell <billo@ca.ibm.com>
|
Bill O'Farrell <billo@ca.ibm.com>
|
||||||
Bill Prin <waprin@google.com>
|
Bill Prin <waprin@google.com>
|
||||||
|
|
@ -401,6 +407,7 @@ Chris Zou <chriszou@ca.ibm.com>
|
||||||
Christian Alexander <christian@linux.com>
|
Christian Alexander <christian@linux.com>
|
||||||
Christian Couder <chriscool@tuxfamily.org>
|
Christian Couder <chriscool@tuxfamily.org>
|
||||||
Christian Himpel <chressie@googlemail.com> <chressie@gmail.com>
|
Christian Himpel <chressie@googlemail.com> <chressie@gmail.com>
|
||||||
|
Christian Muehlhaeuser <muesli@gmail.com>
|
||||||
Christian Pellegrin <chri@evolware.org>
|
Christian Pellegrin <chri@evolware.org>
|
||||||
Christian R. Petrin <christianpetrin@gmail.com>
|
Christian R. Petrin <christianpetrin@gmail.com>
|
||||||
Christine Hansmann <chhansmann@gmail.com>
|
Christine Hansmann <chhansmann@gmail.com>
|
||||||
|
|
@ -481,6 +488,7 @@ Daria Kolistratova <daria.kolistratova@intel.com>
|
||||||
Darien Raymond <admin@v2ray.com>
|
Darien Raymond <admin@v2ray.com>
|
||||||
Darren Elwood <darren@textnode.com>
|
Darren Elwood <darren@textnode.com>
|
||||||
Darren Grant <darren.e.grant@gmail.com>
|
Darren Grant <darren.e.grant@gmail.com>
|
||||||
|
Darren McCleary <darren.rmc@gmail.com>
|
||||||
Darshan Parajuli <parajulidarshan@gmail.com>
|
Darshan Parajuli <parajulidarshan@gmail.com>
|
||||||
Datong Sun <dndx@idndx.com>
|
Datong Sun <dndx@idndx.com>
|
||||||
Dave Borowitz <dborowitz@google.com>
|
Dave Borowitz <dborowitz@google.com>
|
||||||
|
|
@ -501,6 +509,7 @@ David Chase <drchase@google.com>
|
||||||
David Covert <davidhcovert@gmail.com>
|
David Covert <davidhcovert@gmail.com>
|
||||||
David Crawshaw <david.crawshaw@zentus.com> <crawshaw@google.com> <crawshaw@golang.org>
|
David Crawshaw <david.crawshaw@zentus.com> <crawshaw@google.com> <crawshaw@golang.org>
|
||||||
David du Colombier <0intro@gmail.com>
|
David du Colombier <0intro@gmail.com>
|
||||||
|
David Finkel <david.finkel@gmail.com>
|
||||||
David Forsythe <dforsythe@gmail.com>
|
David Forsythe <dforsythe@gmail.com>
|
||||||
David G. Andersen <dave.andersen@gmail.com>
|
David G. Andersen <dave.andersen@gmail.com>
|
||||||
David Glasser <glasser@meteor.com>
|
David Glasser <glasser@meteor.com>
|
||||||
|
|
@ -594,6 +603,7 @@ Dustin Shields-Cloues <dcloues@gmail.com>
|
||||||
Dvir Volk <dvir@everything.me> <dvirsky@gmail.com>
|
Dvir Volk <dvir@everything.me> <dvirsky@gmail.com>
|
||||||
Dylan Waits <dylan@waits.io>
|
Dylan Waits <dylan@waits.io>
|
||||||
Edan Bedrik <3d4nb3@gmail.com>
|
Edan Bedrik <3d4nb3@gmail.com>
|
||||||
|
Eddie Scholtz <escholtz@google.com>
|
||||||
Eden Li <eden.li@gmail.com>
|
Eden Li <eden.li@gmail.com>
|
||||||
Eduard Urbach <e.urbach@gmail.com>
|
Eduard Urbach <e.urbach@gmail.com>
|
||||||
Eduardo Ramalho <eduardo.ramalho@gmail.com>
|
Eduardo Ramalho <eduardo.ramalho@gmail.com>
|
||||||
|
|
@ -763,9 +773,12 @@ GitHub User @pityonline (438222) <pityonline@gmail.com>
|
||||||
GitHub User @pytimer (17105586) <lixin20101023@gmail.com>
|
GitHub User @pytimer (17105586) <lixin20101023@gmail.com>
|
||||||
GitHub User @saitarunreddy (21041941) <saitarunreddypalla@gmail.com>
|
GitHub User @saitarunreddy (21041941) <saitarunreddypalla@gmail.com>
|
||||||
GitHub User @shogo-ma (9860598) <Choroma194@gmail.com>
|
GitHub User @shogo-ma (9860598) <Choroma194@gmail.com>
|
||||||
|
GitHub User @tatsumack (4510569) <tatsu.mack@gmail.com>
|
||||||
GitHub User @tell-k (26263) <ffk2005@gmail.com>
|
GitHub User @tell-k (26263) <ffk2005@gmail.com>
|
||||||
GitHub User @uhei (2116845) <uhei@users.noreply.github.com>
|
GitHub User @uhei (2116845) <uhei@users.noreply.github.com>
|
||||||
GitHub User @uropek (39370426) <uropek@gmail.com>
|
GitHub User @uropek (39370426) <uropek@gmail.com>
|
||||||
|
GitHub User @utkarsh-extc (53217283) <utkarsh.extc@gmail.com>
|
||||||
|
GitHub User @yuanhh (1298735) <yuan415030@gmail.com>
|
||||||
GitHub User @ZZMarquis (7624583) <zhonglingjian3821@163.com>
|
GitHub User @ZZMarquis (7624583) <zhonglingjian3821@163.com>
|
||||||
Giulio Iotti <dullgiulio@gmail.com>
|
Giulio Iotti <dullgiulio@gmail.com>
|
||||||
Giulio Micheloni <giulio.micheloni@gmail.com>
|
Giulio Micheloni <giulio.micheloni@gmail.com>
|
||||||
|
|
@ -861,6 +874,7 @@ Igor Bernstein <igorbernstein@google.com>
|
||||||
Igor Dolzhikov <bluesriverz@gmail.com>
|
Igor Dolzhikov <bluesriverz@gmail.com>
|
||||||
Igor Vashyst <ivashyst@gmail.com>
|
Igor Vashyst <ivashyst@gmail.com>
|
||||||
Igor Zhilianin <igor.zhilianin@gmail.com>
|
Igor Zhilianin <igor.zhilianin@gmail.com>
|
||||||
|
Illya Yalovyy <yalovoy@gmail.com>
|
||||||
Ilya Tocar <ilya.tocar@intel.com>
|
Ilya Tocar <ilya.tocar@intel.com>
|
||||||
INADA Naoki <songofacandy@gmail.com>
|
INADA Naoki <songofacandy@gmail.com>
|
||||||
Inanc Gumus <m@inanc.io>
|
Inanc Gumus <m@inanc.io>
|
||||||
|
|
@ -905,6 +919,7 @@ James Clarke <jrtc27@jrtc27.com>
|
||||||
James Cowgill <James.Cowgill@imgtec.com>
|
James Cowgill <James.Cowgill@imgtec.com>
|
||||||
James Craig Burley <james-github@burleyarch.com>
|
James Craig Burley <james-github@burleyarch.com>
|
||||||
James David Chalfant <james.chalfant@gmail.com>
|
James David Chalfant <james.chalfant@gmail.com>
|
||||||
|
James Eady <jmeady@google.com>
|
||||||
James Fysh <james.fysh@gmail.com>
|
James Fysh <james.fysh@gmail.com>
|
||||||
James Gray <james@james4k.com>
|
James Gray <james@james4k.com>
|
||||||
James Hartig <fastest963@gmail.com>
|
James Hartig <fastest963@gmail.com>
|
||||||
|
|
@ -937,6 +952,7 @@ Jan Lehnardt <jan@apache.org>
|
||||||
Jan Mercl <0xjnml@gmail.com> <befelemepeseveze@gmail.com>
|
Jan Mercl <0xjnml@gmail.com> <befelemepeseveze@gmail.com>
|
||||||
Jan Newmarch <jan.newmarch@gmail.com>
|
Jan Newmarch <jan.newmarch@gmail.com>
|
||||||
Jan Pilzer <jan.pilzer@gmx.de>
|
Jan Pilzer <jan.pilzer@gmx.de>
|
||||||
|
Jan Steinke <jan.steinke@gmail.com>
|
||||||
Jan Ziak <0xe2.0x9a.0x9b@gmail.com>
|
Jan Ziak <0xe2.0x9a.0x9b@gmail.com>
|
||||||
Jani Monoses <jani.monoses@ubuntu.com> <jani.monoses@gmail.com>
|
Jani Monoses <jani.monoses@ubuntu.com> <jani.monoses@gmail.com>
|
||||||
Jannis Andrija Schnitzer <jannis@schnitzer.im>
|
Jannis Andrija Schnitzer <jannis@schnitzer.im>
|
||||||
|
|
@ -954,6 +970,7 @@ Jason Smale <jsmale@zendesk.com>
|
||||||
Jason Travis <infomaniac7@gmail.com>
|
Jason Travis <infomaniac7@gmail.com>
|
||||||
Jason Wangsadinata <jwangsadinata@gmail.com>
|
Jason Wangsadinata <jwangsadinata@gmail.com>
|
||||||
Javier Kohen <jkohen@google.com>
|
Javier Kohen <jkohen@google.com>
|
||||||
|
Javier Revillas <jrevillas@massivedynamic.io>
|
||||||
Javier Segura <javism@gmail.com>
|
Javier Segura <javism@gmail.com>
|
||||||
Jay Conrod <jayconrod@google.com>
|
Jay Conrod <jayconrod@google.com>
|
||||||
Jay Taylor <outtatime@gmail.com>
|
Jay Taylor <outtatime@gmail.com>
|
||||||
|
|
@ -1071,6 +1088,8 @@ Jordan Krage <jmank88@gmail.com>
|
||||||
Jordan Lewis <jordanthelewis@gmail.com>
|
Jordan Lewis <jordanthelewis@gmail.com>
|
||||||
Jordan Liggitt <liggitt@google.com>
|
Jordan Liggitt <liggitt@google.com>
|
||||||
Jordan Rhee <jordanrh@microsoft.com>
|
Jordan Rhee <jordanrh@microsoft.com>
|
||||||
|
Jordi Martin <jordimartin@gmail.com>
|
||||||
|
Jorge Araya <jorgejavieran@yahoo.com.mx>
|
||||||
Jos Visser <josv@google.com>
|
Jos Visser <josv@google.com>
|
||||||
Jose Luis Vázquez González <josvazg@gmail.com>
|
Jose Luis Vázquez González <josvazg@gmail.com>
|
||||||
Joseph Bonneau <jcb@google.com>
|
Joseph Bonneau <jcb@google.com>
|
||||||
|
|
@ -1114,6 +1133,7 @@ Justin Gracenin <jgracenin@gmail.com>
|
||||||
Justin Li <git@justinli.net>
|
Justin Li <git@justinli.net>
|
||||||
Justin Nuß <nuss.justin@gmail.com>
|
Justin Nuß <nuss.justin@gmail.com>
|
||||||
Justyn Temme <justyntemme@gmail.com>
|
Justyn Temme <justyntemme@gmail.com>
|
||||||
|
Kelly Heller <pestophagous@gmail.com>
|
||||||
Kai Backman <kaib@golang.org>
|
Kai Backman <kaib@golang.org>
|
||||||
Kai Dong <dokia2357@gmail.com>
|
Kai Dong <dokia2357@gmail.com>
|
||||||
Kai Trukenmüller <ktye78@gmail.com>
|
Kai Trukenmüller <ktye78@gmail.com>
|
||||||
|
|
@ -1159,6 +1179,7 @@ Kenta Mori <zoncoen@gmail.com>
|
||||||
Ketan Parmar <ketanbparmar@gmail.com>
|
Ketan Parmar <ketanbparmar@gmail.com>
|
||||||
Kevin Ballard <kevin@sb.org>
|
Kevin Ballard <kevin@sb.org>
|
||||||
Kevin Burke <kev@inburke.com>
|
Kevin Burke <kev@inburke.com>
|
||||||
|
Kevin Gillette <extemporalgenome@gmail.com>
|
||||||
Kevin Kirsche <kev.kirsche@gmail.com>
|
Kevin Kirsche <kev.kirsche@gmail.com>
|
||||||
Kevin Klues <klueska@gmail.com> <klueska@google.com>
|
Kevin Klues <klueska@gmail.com> <klueska@google.com>
|
||||||
Kevin Malachowski <chowski@google.com>
|
Kevin Malachowski <chowski@google.com>
|
||||||
|
|
@ -1284,6 +1305,7 @@ Marius A. Eriksen <marius@grailbio.com>
|
||||||
Marius Nuennerich <mnu@google.com>
|
Marius Nuennerich <mnu@google.com>
|
||||||
Mark Adams <mark@markadams.me>
|
Mark Adams <mark@markadams.me>
|
||||||
Mark Bucciarelli <mkbucc@gmail.com>
|
Mark Bucciarelli <mkbucc@gmail.com>
|
||||||
|
Mark Glines <mark@glines.org>
|
||||||
Mark Harrison <marhar@google.com>
|
Mark Harrison <marhar@google.com>
|
||||||
Mark Percival <m@mdp.im>
|
Mark Percival <m@mdp.im>
|
||||||
Mark Pulford <mark@kyne.com.au>
|
Mark Pulford <mark@kyne.com.au>
|
||||||
|
|
@ -1480,6 +1502,7 @@ Muir Manders <muir@mnd.rs>
|
||||||
Mura Li <mura_li@castech.com.tw>
|
Mura Li <mura_li@castech.com.tw>
|
||||||
Mykhailo Lesyk <mikhail@lesyk.org>
|
Mykhailo Lesyk <mikhail@lesyk.org>
|
||||||
Nan Deng <monnand@gmail.com>
|
Nan Deng <monnand@gmail.com>
|
||||||
|
Nao Yonashiro <owan.orisano@gmail.com>
|
||||||
Naoki Kanatani <k12naoki@gmail.com>
|
Naoki Kanatani <k12naoki@gmail.com>
|
||||||
Nate Wilkinson <nathanwilk7@gmail.com>
|
Nate Wilkinson <nathanwilk7@gmail.com>
|
||||||
Nathan Cantelmo <n.cantelmo@gmail.com>
|
Nathan Cantelmo <n.cantelmo@gmail.com>
|
||||||
|
|
@ -1566,6 +1589,7 @@ Paolo Giarrusso <p.giarrusso@gmail.com>
|
||||||
Paolo Martini <mrtnpaolo@gmail.com>
|
Paolo Martini <mrtnpaolo@gmail.com>
|
||||||
Parker Moore <parkrmoore@gmail.com>
|
Parker Moore <parkrmoore@gmail.com>
|
||||||
Parminder Singh <parmsingh101@gmail.com>
|
Parminder Singh <parmsingh101@gmail.com>
|
||||||
|
Pascal Dierich <pascal@pascaldierich.com>
|
||||||
Pascal S. de Kloe <pascal@quies.net>
|
Pascal S. de Kloe <pascal@quies.net>
|
||||||
Pat Moroney <pat@pat.email>
|
Pat Moroney <pat@pat.email>
|
||||||
Patrick Barker <barkerp@vmware.com>
|
Patrick Barker <barkerp@vmware.com>
|
||||||
|
|
@ -1658,6 +1682,7 @@ Prasanna Swaminathan <prasanna@mediamath.com>
|
||||||
Prashant Varanasi <prashant@prashantv.com>
|
Prashant Varanasi <prashant@prashantv.com>
|
||||||
Pravendra Singh <hackpravj@gmail.com>
|
Pravendra Singh <hackpravj@gmail.com>
|
||||||
Preetam Jinka <pj@preet.am>
|
Preetam Jinka <pj@preet.am>
|
||||||
|
Pure White <wu.purewhite@gmail.com>
|
||||||
Qais Patankar <qaisjp@gmail.com>
|
Qais Patankar <qaisjp@gmail.com>
|
||||||
Qiuxuan Zhu <ilsh1022@gmail.com>
|
Qiuxuan Zhu <ilsh1022@gmail.com>
|
||||||
Quan Tran <qeed.quan@gmail.com>
|
Quan Tran <qeed.quan@gmail.com>
|
||||||
|
|
@ -1774,6 +1799,7 @@ Sad Pencil <qh06@qq.com>
|
||||||
Sai Cheemalapati <saicheems@google.com>
|
Sai Cheemalapati <saicheems@google.com>
|
||||||
Sakeven Jiang <jc5930@sina.cn>
|
Sakeven Jiang <jc5930@sina.cn>
|
||||||
Salmān Aljammāz <s@0x65.net>
|
Salmān Aljammāz <s@0x65.net>
|
||||||
|
Sam Arnold <sarnold64@bloomberg.net>
|
||||||
Sam Boyer <tech@samboyer.org>
|
Sam Boyer <tech@samboyer.org>
|
||||||
Sam Ding <samding@ca.ibm.com>
|
Sam Ding <samding@ca.ibm.com>
|
||||||
Sam Hug <samuel.b.hug@gmail.com>
|
Sam Hug <samuel.b.hug@gmail.com>
|
||||||
|
|
@ -1785,6 +1811,7 @@ Sami Pönkänen <sami.ponkanen@gmail.com>
|
||||||
Samuel Kelemen <SCKelemen@users.noreply.github.com>
|
Samuel Kelemen <SCKelemen@users.noreply.github.com>
|
||||||
Samuel Tan <samueltan@google.com>
|
Samuel Tan <samueltan@google.com>
|
||||||
Samuele Pedroni <pedronis@lucediurna.net>
|
Samuele Pedroni <pedronis@lucediurna.net>
|
||||||
|
Sander van Harmelen <sander@vanharmelen.nl>
|
||||||
Sanjay Menakuru <balasanjay@gmail.com>
|
Sanjay Menakuru <balasanjay@gmail.com>
|
||||||
Santhosh Kumar Tekuri <santhosh.tekuri@gmail.com>
|
Santhosh Kumar Tekuri <santhosh.tekuri@gmail.com>
|
||||||
Sarah Adams <shadams@google.com>
|
Sarah Adams <shadams@google.com>
|
||||||
|
|
@ -1814,6 +1841,7 @@ Sebastien Williams-Wynn <sebastien@cytora.com>
|
||||||
Segev Finer <segev208@gmail.com>
|
Segev Finer <segev208@gmail.com>
|
||||||
Seiji Takahashi <timaki.st@gmail.com>
|
Seiji Takahashi <timaki.st@gmail.com>
|
||||||
Sergei Skorobogatov <skorobo@rambler.ru>
|
Sergei Skorobogatov <skorobo@rambler.ru>
|
||||||
|
Sergei Zagurskii <gvozdoder@gmail.com>
|
||||||
Sergey 'SnakE' Gromov <snake.scaly@gmail.com>
|
Sergey 'SnakE' Gromov <snake.scaly@gmail.com>
|
||||||
Sergey Arseev <sergey.arseev@intel.com>
|
Sergey Arseev <sergey.arseev@intel.com>
|
||||||
Sergey Dobrodey <sergey.dobrodey@synesis.ru>
|
Sergey Dobrodey <sergey.dobrodey@synesis.ru>
|
||||||
|
|
@ -1845,6 +1873,7 @@ Shijie Hao <haormj@gmail.com>
|
||||||
Shinji Tanaka <shinji.tanaka@gmail.com>
|
Shinji Tanaka <shinji.tanaka@gmail.com>
|
||||||
Shintaro Kaneko <kaneshin0120@gmail.com>
|
Shintaro Kaneko <kaneshin0120@gmail.com>
|
||||||
Shivakumar GN <shivakumar.gn@gmail.com>
|
Shivakumar GN <shivakumar.gn@gmail.com>
|
||||||
|
Shivani Singhal <shivani.singhal2804@gmail.com>
|
||||||
Shivansh Rai <shivansh@freebsd.org>
|
Shivansh Rai <shivansh@freebsd.org>
|
||||||
Shubham Sharma <shubham.sha12@gmail.com>
|
Shubham Sharma <shubham.sha12@gmail.com>
|
||||||
Shun Fan <sfan@google.com>
|
Shun Fan <sfan@google.com>
|
||||||
|
|
@ -1865,6 +1894,7 @@ StalkR <stalkr@stalkr.net>
|
||||||
Stan Schwertly <stan@schwertly.com>
|
Stan Schwertly <stan@schwertly.com>
|
||||||
Stanislav Afanasev <php.progger@gmail.com>
|
Stanislav Afanasev <php.progger@gmail.com>
|
||||||
Steeve Morin <steeve.morin@gmail.com>
|
Steeve Morin <steeve.morin@gmail.com>
|
||||||
|
Stefan Baebler <sbaebler@outbrain.com>
|
||||||
Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com>
|
Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com>
|
||||||
Stepan Shabalin <neverliberty@gmail.com>
|
Stepan Shabalin <neverliberty@gmail.com>
|
||||||
Stephan Renatus <srenatus@chef.io>
|
Stephan Renatus <srenatus@chef.io>
|
||||||
|
|
@ -1951,6 +1981,7 @@ Thomas Wanielista <tomwans@gmail.com>
|
||||||
Thorben Krueger <thorben.krueger@gmail.com>
|
Thorben Krueger <thorben.krueger@gmail.com>
|
||||||
Thordur Bjornsson <thorduri@secnorth.net>
|
Thordur Bjornsson <thorduri@secnorth.net>
|
||||||
Tiago Queiroz <contato@tiago.eti.br>
|
Tiago Queiroz <contato@tiago.eti.br>
|
||||||
|
Tianon Gravi <admwiggin@gmail.com>
|
||||||
Tilman Dilo <tilman.dilo@gmail.com>
|
Tilman Dilo <tilman.dilo@gmail.com>
|
||||||
Tim Cooijmans <timcooijmans@gmail.com>
|
Tim Cooijmans <timcooijmans@gmail.com>
|
||||||
Tim Cooper <tim.cooper@layeh.com>
|
Tim Cooper <tim.cooper@layeh.com>
|
||||||
|
|
@ -1991,6 +2022,7 @@ Tony Walker <walkert.uk@gmail.com>
|
||||||
Tooru Takahashi <tooru.takahashi134@gmail.com>
|
Tooru Takahashi <tooru.takahashi134@gmail.com>
|
||||||
Tor Andersson <tor.andersson@gmail.com>
|
Tor Andersson <tor.andersson@gmail.com>
|
||||||
Tormod Erevik Lea <tormodlea@gmail.com>
|
Tormod Erevik Lea <tormodlea@gmail.com>
|
||||||
|
Toshihiro Shiino <shiino.toshihiro@gmail.com>
|
||||||
Toshiki Shima <hayabusa1419@gmail.com>
|
Toshiki Shima <hayabusa1419@gmail.com>
|
||||||
Totoro W <tw19881113@gmail.com>
|
Totoro W <tw19881113@gmail.com>
|
||||||
Travis Bischel <travis.bischel@gmail.com>
|
Travis Bischel <travis.bischel@gmail.com>
|
||||||
|
|
@ -2052,6 +2084,7 @@ Volker Dobler <dr.volker.dobler@gmail.com>
|
||||||
Volodymyr Paprotski <vpaprots@ca.ibm.com>
|
Volodymyr Paprotski <vpaprots@ca.ibm.com>
|
||||||
W. Trevor King <wking@tremily.us>
|
W. Trevor King <wking@tremily.us>
|
||||||
Wade Simmons <wade@wades.im>
|
Wade Simmons <wade@wades.im>
|
||||||
|
Wagner Riffel <wgrriffel@gmail.com>
|
||||||
Walter Poupore <wpoupore@google.com>
|
Walter Poupore <wpoupore@google.com>
|
||||||
Wander Lairson Costa <wcosta@mozilla.com>
|
Wander Lairson Costa <wcosta@mozilla.com>
|
||||||
Warren Fernandes <warren.f.fernandes@gmail.com>
|
Warren Fernandes <warren.f.fernandes@gmail.com>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
## Supported Versions
|
## Supported Versions
|
||||||
|
|
||||||
We support the past two Go releases (for example, Go 1.11.x and Go 1.12.x).
|
We support the past two Go releases (for example, Go 1.12.x and Go 1.13.x).
|
||||||
|
|
||||||
See https://golang.org/wiki/Go-Release-Cycle and in particular the
|
See https://golang.org/wiki/Go-Release-Cycle and in particular the
|
||||||
[Release Maintenance](https://github.com/golang/go/wiki/Go-Release-Cycle#release-maintenance)
|
[Release Maintenance](https://github.com/golang/go/wiki/Go-Release-Cycle#release-maintenance)
|
||||||
|
|
|
||||||
|
|
@ -459,3 +459,4 @@ pkg syscall (freebsd-arm-cgo), type Statfs_t struct, Mntfromname [88]int8
|
||||||
pkg syscall (freebsd-arm-cgo), type Statfs_t struct, Mntonname [88]int8
|
pkg syscall (freebsd-arm-cgo), type Statfs_t struct, Mntonname [88]int8
|
||||||
pkg text/scanner, const GoTokens = 1012
|
pkg text/scanner, const GoTokens = 1012
|
||||||
pkg unicode, const Version = "10.0.0"
|
pkg unicode, const Version = "10.0.0"
|
||||||
|
pkg unicode, const Version = "11.0.0"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
pkg unicode, const Version = "12.0.0"
|
||||||
|
pkg unicode, var Elymaic *RangeTable
|
||||||
|
pkg unicode, var Nandinagari *RangeTable
|
||||||
|
pkg unicode, var Nyiakeng_Puachue_Hmong *RangeTable
|
||||||
|
pkg unicode, var Wancho *RangeTable
|
||||||
|
|
@ -90,7 +90,7 @@ func getTitle(w http.ResponseWriter, r *http.Request) (string, error) {
|
||||||
m := validPath.FindStringSubmatch(r.URL.Path)
|
m := validPath.FindStringSubmatch(r.URL.Path)
|
||||||
if m == nil {
|
if m == nil {
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
return "", errors.New("Invalid Page Title")
|
return "", errors.New("invalid Page Title")
|
||||||
}
|
}
|
||||||
return m[2], nil // The title is the second subexpression.
|
return m[2], nil // The title is the second subexpression.
|
||||||
}
|
}
|
||||||
|
|
|
||||||
17
doc/asm.html
17
doc/asm.html
|
|
@ -832,27 +832,16 @@ The other extensions include <code>SXTH</code> (16-bit), <code>SXTW</code> (32-b
|
||||||
Reference: <a href="/pkg/cmd/internal/obj/arm64">Go ARM64 Assembly Instructions Reference Manual</a>
|
Reference: <a href="/pkg/cmd/internal/obj/arm64">Go ARM64 Assembly Instructions Reference Manual</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3 id="ppc64">64-bit PowerPC, a.k.a. ppc64</h3>
|
<h3 id="ppc64">PPC64</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The 64-bit PowerPC port is in an experimental state.
|
This assembler is used by GOARCH values ppc64 and ppc64le.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Addressing modes:
|
Reference: <a href="/pkg/cmd/internal/obj/ppc64">Go PPC64 Assembly Instructions Reference Manual</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<code>(R5)(R6*1)</code>: The location at <code>R5</code> plus <code>R6</code>. It is a scaled
|
|
||||||
mode as on the x86, but the only scale allowed is <code>1</code>.
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<code>(R5+R6)</code>: Alias for (R5)(R6*1)
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3 id="s390x">IBM z/Architecture, a.k.a. s390x</h3>
|
<h3 id="s390x">IBM z/Architecture, a.k.a. s390x</h3>
|
||||||
|
|
|
||||||
648
doc/code.html
648
doc/code.html
|
|
@ -1,648 +0,0 @@
|
||||||
<!--{
|
|
||||||
"Title": "How to Write Go Code"
|
|
||||||
}-->
|
|
||||||
|
|
||||||
<h2 id="Introduction">Introduction</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This document demonstrates the development of a simple Go package and
|
|
||||||
introduces the <a href="/cmd/go/">go tool</a>, the standard way to fetch,
|
|
||||||
build, and install Go packages and commands.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The <code>go</code> tool requires you to organize your code in a specific
|
|
||||||
way. Please read this document carefully.
|
|
||||||
It explains the simplest way to get up and running with your Go installation.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
A similar explanation is available as a
|
|
||||||
<a href="//www.youtube.com/watch?v=XCsL89YtqCs">screencast</a>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h2 id="Organization">Code organization</h2>
|
|
||||||
|
|
||||||
<h3 id="Overview">Overview</h3>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>Go programmers typically keep all their Go code in a single <i>workspace</i>.</li>
|
|
||||||
<li>A workspace contains many version control <i>repositories</i>
|
|
||||||
(managed by Git, for example).</li>
|
|
||||||
<li>Each repository contains one or more <i>packages</i>.</li>
|
|
||||||
<li>Each package consists of one or more Go source files in a single directory.</li>
|
|
||||||
<li>The path to a package's directory determines its <i>import path</i>.</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Note that this differs from other programming environments in which every
|
|
||||||
project has a separate workspace and workspaces are closely tied to version
|
|
||||||
control repositories.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="Workspaces">Workspaces</h3>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
A workspace is a directory hierarchy with two directories at its root:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><code>src</code> contains Go source files, and
|
|
||||||
<li><code>bin</code> contains executable commands.
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The <code>go</code> tool builds and installs binaries to the <code>bin</code> directory.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The <code>src</code> subdirectory typically contains multiple version control
|
|
||||||
repositories (such as for Git or Mercurial) that track the development of one
|
|
||||||
or more source packages.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
To give you an idea of how a workspace looks in practice, here's an example:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
bin/
|
|
||||||
hello # command executable
|
|
||||||
outyet # command executable
|
|
||||||
src/
|
|
||||||
<a href="https://github.com/golang/example/">github.com/golang/example/</a>
|
|
||||||
.git/ # Git repository metadata
|
|
||||||
hello/
|
|
||||||
hello.go # command source
|
|
||||||
outyet/
|
|
||||||
main.go # command source
|
|
||||||
main_test.go # test source
|
|
||||||
stringutil/
|
|
||||||
reverse.go # package source
|
|
||||||
reverse_test.go # test source
|
|
||||||
<a href="https://golang.org/x/image/">golang.org/x/image/</a>
|
|
||||||
.git/ # Git repository metadata
|
|
||||||
bmp/
|
|
||||||
reader.go # package source
|
|
||||||
writer.go # package source
|
|
||||||
... (many more repositories and packages omitted) ...
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The tree above shows a workspace containing two repositories
|
|
||||||
(<code>example</code> and <code>image</code>).
|
|
||||||
The <code>example</code> repository contains two commands (<code>hello</code>
|
|
||||||
and <code>outyet</code>) and one library (<code>stringutil</code>).
|
|
||||||
The <code>image</code> repository contains the <code>bmp</code> package
|
|
||||||
and <a href="https://godoc.org/golang.org/x/image">several others</a>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
A typical workspace contains many source repositories containing many
|
|
||||||
packages and commands. Most Go programmers keep <i>all</i> their Go source code
|
|
||||||
and dependencies in a single workspace.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Note that symbolic links should <b>not</b> be used to link files or directories into your workspace.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Commands and libraries are built from different kinds of source packages.
|
|
||||||
We will discuss the distinction <a href="#PackageNames">later</a>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h3 id="GOPATH">The <code>GOPATH</code> environment variable</h3>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The <code>GOPATH</code> environment variable specifies the location of your
|
|
||||||
workspace. It defaults to a directory named <code>go</code> inside your home directory,
|
|
||||||
so <code>$HOME/go</code> on Unix,
|
|
||||||
<code>$home/go</code> on Plan 9,
|
|
||||||
and <code>%USERPROFILE%\go</code> (usually <code>C:\Users\YourName\go</code>) on Windows.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If you would like to work in a different location, you will need to
|
|
||||||
<a href="https://golang.org/wiki/SettingGOPATH">set <code>GOPATH</code></a>
|
|
||||||
to the path to that directory.
|
|
||||||
(Another common setup is to set <code>GOPATH=$HOME</code>.)
|
|
||||||
Note that <code>GOPATH</code> must <b>not</b> be the
|
|
||||||
same path as your Go installation.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The command <code>go</code> <code>env</code> <code>GOPATH</code>
|
|
||||||
prints the effective current <code>GOPATH</code>;
|
|
||||||
it prints the default location if the environment variable is unset.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
For convenience, add the workspace's <code>bin</code> subdirectory
|
|
||||||
to your <code>PATH</code>:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>export PATH=$PATH:$(go env GOPATH)/bin</b>
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The scripts in the rest of this document use <code>$GOPATH</code>
|
|
||||||
instead of <code>$(go env GOPATH)</code> for brevity.
|
|
||||||
To make the scripts run as written
|
|
||||||
if you have not set GOPATH,
|
|
||||||
you can substitute $HOME/go in those commands
|
|
||||||
or else run:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>export GOPATH=$(go env GOPATH)</b>
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
To learn more about the <code>GOPATH</code> environment variable, see
|
|
||||||
<a href="/cmd/go/#hdr-GOPATH_environment_variable"><code>'go help gopath'</code></a>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
To use a custom workspace location,
|
|
||||||
<a href="https://golang.org/wiki/SettingGOPATH">set the <code>GOPATH</code> environment variable</a>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="ImportPaths">Import paths</h3>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
An <i>import path</i> is a string that uniquely identifies a package.
|
|
||||||
A package's import path corresponds to its location inside a workspace
|
|
||||||
or in a remote repository (explained below).
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The packages from the standard library are given short import paths such as
|
|
||||||
<code>"fmt"</code> and <code>"net/http"</code>.
|
|
||||||
For your own packages, you must choose a base path that is unlikely to
|
|
||||||
collide with future additions to the standard library or other external
|
|
||||||
libraries.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If you keep your code in a source repository somewhere, then you should use the
|
|
||||||
root of that source repository as your base path.
|
|
||||||
For instance, if you have a <a href="https://github.com/">GitHub</a> account at
|
|
||||||
<code>github.com/user</code>, that should be your base path.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Note that you don't need to publish your code to a remote repository before you
|
|
||||||
can build it. It's just a good habit to organize your code as if you will
|
|
||||||
publish it someday. In practice you can choose any arbitrary path name,
|
|
||||||
as long as it is unique to the standard library and greater Go ecosystem.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
We'll use <code>github.com/user</code> as our base path. Create a directory
|
|
||||||
inside your workspace in which to keep source code:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>mkdir -p $GOPATH/src/github.com/user</b>
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
|
|
||||||
<h3 id="Command">Your first program</h3>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
To compile and run a simple program, first choose a package path (we'll use
|
|
||||||
<code>github.com/user/hello</code>) and create a corresponding package directory
|
|
||||||
inside your workspace:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>mkdir $GOPATH/src/github.com/user/hello</b>
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Next, create a file named <code>hello.go</code> inside that directory,
|
|
||||||
containing the following Go code.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fmt.Println("Hello, world.")
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Now you can build and install that program with the <code>go</code> tool:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>go install github.com/user/hello</b>
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Note that you can run this command from anywhere on your system. The
|
|
||||||
<code>go</code> tool finds the source code by looking for the
|
|
||||||
<code>github.com/user/hello</code> package inside the workspace specified by
|
|
||||||
<code>GOPATH</code>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
You can also omit the package path if you run <code>go install</code> from the
|
|
||||||
package directory:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>cd $GOPATH/src/github.com/user/hello</b>
|
|
||||||
$ <b>go install</b>
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This command builds the <code>hello</code> command, producing an executable
|
|
||||||
binary. It then installs that binary to the workspace's <code>bin</code>
|
|
||||||
directory as <code>hello</code> (or, under Windows, <code>hello.exe</code>).
|
|
||||||
In our example, that will be <code>$GOPATH/bin/hello</code>, which is
|
|
||||||
<code>$HOME/go/bin/hello</code>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The <code>go</code> tool will only print output when an error occurs, so if
|
|
||||||
these commands produce no output they have executed successfully.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
You can now run the program by typing its full path at the command line:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>$GOPATH/bin/hello</b>
|
|
||||||
Hello, world.
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Or, as you have added <code>$GOPATH/bin</code> to your <code>PATH</code>,
|
|
||||||
just type the binary name:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>hello</b>
|
|
||||||
Hello, world.
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If you're using a source control system, now would be a good time to initialize
|
|
||||||
a repository, add the files, and commit your first change. Again, this step is
|
|
||||||
optional: you do not need to use source control to write Go code.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>cd $GOPATH/src/github.com/user/hello</b>
|
|
||||||
$ <b>git init</b>
|
|
||||||
Initialized empty Git repository in /home/user/go/src/github.com/user/hello/.git/
|
|
||||||
$ <b>git add hello.go</b>
|
|
||||||
$ <b>git commit -m "initial commit"</b>
|
|
||||||
[master (root-commit) 0b4507d] initial commit
|
|
||||||
1 file changed, 7 insertion(+)
|
|
||||||
create mode 100644 hello.go
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Pushing the code to a remote repository is left as an exercise for the reader.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h3 id="Library">Your first library</h3>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Let's write a library and use it from the <code>hello</code> program.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Again, the first step is to choose a package path (we'll use
|
|
||||||
<code>github.com/user/stringutil</code>) and create the package directory:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>mkdir $GOPATH/src/github.com/user/stringutil</b>
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Next, create a file named <code>reverse.go</code> in that directory with the
|
|
||||||
following contents.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
// Package stringutil contains utility functions for working with strings.
|
|
||||||
package stringutil
|
|
||||||
|
|
||||||
// Reverse returns its argument string reversed rune-wise left to right.
|
|
||||||
func Reverse(s string) string {
|
|
||||||
r := []rune(s)
|
|
||||||
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
|
|
||||||
r[i], r[j] = r[j], r[i]
|
|
||||||
}
|
|
||||||
return string(r)
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Now, test that the package compiles with <code>go build</code>:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>go build github.com/user/stringutil</b>
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Or, if you are working in the package's source directory, just:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>go build</b>
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This won't produce an output file.
|
|
||||||
Instead it saves the compiled package in the local build cache.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
After confirming that the <code>stringutil</code> package builds,
|
|
||||||
modify your original <code>hello.go</code> (which is in
|
|
||||||
<code>$GOPATH/src/github.com/user/hello</code>) to use it:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
<b>"github.com/user/stringutil"</b>
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
fmt.Println(stringutil.Reverse("!oG ,olleH"))
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Install the <code>hello</code> program:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>go install github.com/user/hello</b>
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Running the new version of the program, you should see a new, reversed message:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>hello</b>
|
|
||||||
Hello, Go!
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
After the steps above, your workspace should look like this:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
bin/
|
|
||||||
hello # command executable
|
|
||||||
src/
|
|
||||||
github.com/user/
|
|
||||||
hello/
|
|
||||||
hello.go # command source
|
|
||||||
stringutil/
|
|
||||||
reverse.go # package source
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<h3 id="PackageNames">Package names</h3>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The first statement in a Go source file must be
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
package <i>name</i>
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
where <code><i>name</i></code> is the package's default name for imports.
|
|
||||||
(All files in a package must use the same <code><i>name</i></code>.)
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Go's convention is that the package name is the last element of the
|
|
||||||
import path: the package imported as "<code>crypto/rot13</code>"
|
|
||||||
should be named <code>rot13</code>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Executable commands must always use <code>package main</code>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
There is no requirement that package names be unique
|
|
||||||
across all packages linked into a single binary,
|
|
||||||
only that the import paths (their full file names) be unique.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
See <a href="/doc/effective_go.html#names">Effective Go</a> to learn more about
|
|
||||||
Go's naming conventions.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h2 id="Testing">Testing</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Go has a lightweight test framework composed of the <code>go test</code>
|
|
||||||
command and the <code>testing</code> package.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
You write a test by creating a file with a name ending in <code>_test.go</code>
|
|
||||||
that contains functions named <code>TestXXX</code> with signature
|
|
||||||
<code>func (t *testing.T)</code>.
|
|
||||||
The test framework runs each such function;
|
|
||||||
if the function calls a failure function such as <code>t.Error</code> or
|
|
||||||
<code>t.Fail</code>, the test is considered to have failed.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Add a test to the <code>stringutil</code> package by creating the file
|
|
||||||
<code>$GOPATH/src/github.com/user/stringutil/reverse_test.go</code> containing
|
|
||||||
the following Go code.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
package stringutil
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestReverse(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
in, want string
|
|
||||||
}{
|
|
||||||
{"Hello, world", "dlrow ,olleH"},
|
|
||||||
{"Hello, 世界", "界世 ,olleH"},
|
|
||||||
{"", ""},
|
|
||||||
}
|
|
||||||
for _, c := range cases {
|
|
||||||
got := Reverse(c.in)
|
|
||||||
if got != c.want {
|
|
||||||
t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Then run the test with <code>go test</code>:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>go test github.com/user/stringutil</b>
|
|
||||||
ok github.com/user/stringutil 0.165s
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
As always, if you are running the <code>go</code> tool from the package
|
|
||||||
directory, you can omit the package path:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>go test</b>
|
|
||||||
ok github.com/user/stringutil 0.165s
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Run <code><a href="/cmd/go/#hdr-Test_packages">go help test</a></code> and see the
|
|
||||||
<a href="/pkg/testing/">testing package documentation</a> for more detail.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h2 id="remote">Remote packages</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
An import path can describe how to obtain the package source code using a
|
|
||||||
revision control system such as Git or Mercurial. The <code>go</code> tool uses
|
|
||||||
this property to automatically fetch packages from remote repositories.
|
|
||||||
For instance, the examples described in this document are also kept in a
|
|
||||||
Git repository hosted at GitHub
|
|
||||||
<code><a href="https://github.com/golang/example">github.com/golang/example</a></code>.
|
|
||||||
If you include the repository URL in the package's import path,
|
|
||||||
<code>go get</code> will fetch, build, and install it automatically:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
$ <b>go get github.com/golang/example/hello</b>
|
|
||||||
$ <b>$GOPATH/bin/hello</b>
|
|
||||||
Hello, Go examples!
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If the specified package is not present in a workspace, <code>go get</code>
|
|
||||||
will place it inside the first workspace specified by <code>GOPATH</code>.
|
|
||||||
(If the package does already exist, <code>go get</code> skips the remote
|
|
||||||
fetch and behaves the same as <code>go install</code>.)
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
After issuing the above <code>go get</code> command, the workspace directory
|
|
||||||
tree should now look like this:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
bin/
|
|
||||||
hello # command executable
|
|
||||||
src/
|
|
||||||
github.com/golang/example/
|
|
||||||
.git/ # Git repository metadata
|
|
||||||
hello/
|
|
||||||
hello.go # command source
|
|
||||||
stringutil/
|
|
||||||
reverse.go # package source
|
|
||||||
reverse_test.go # test source
|
|
||||||
github.com/user/
|
|
||||||
hello/
|
|
||||||
hello.go # command source
|
|
||||||
stringutil/
|
|
||||||
reverse.go # package source
|
|
||||||
reverse_test.go # test source
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The <code>hello</code> command hosted at GitHub depends on the
|
|
||||||
<code>stringutil</code> package within the same repository. The imports in
|
|
||||||
<code>hello.go</code> file use the same import path convention, so the
|
|
||||||
<code>go get</code> command is able to locate and install the dependent
|
|
||||||
package, too.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
import "github.com/golang/example/stringutil"
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This convention is the easiest way to make your Go packages available for
|
|
||||||
others to use.
|
|
||||||
The <a href="//golang.org/wiki/Projects">Go Wiki</a>
|
|
||||||
and <a href="//godoc.org/">godoc.org</a>
|
|
||||||
provide lists of external Go projects.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
For more information on using remote repositories with the <code>go</code> tool, see
|
|
||||||
<code><a href="/cmd/go/#hdr-Remote_import_paths">go help importpath</a></code>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h2 id="next">What's next</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Subscribe to the
|
|
||||||
<a href="//groups.google.com/group/golang-announce">golang-announce</a>
|
|
||||||
mailing list to be notified when a new stable version of Go is released.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
See <a href="/doc/effective_go.html">Effective Go</a> for tips on writing
|
|
||||||
clear, idiomatic Go code.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Take <a href="//tour.golang.org/">A Tour of Go</a> to learn the language
|
|
||||||
proper.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Visit the <a href="/doc/#articles">documentation page</a> for a set of in-depth
|
|
||||||
articles about the Go language and its libraries and tools.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h2 id="help">Getting help</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
For real-time help, ask the helpful gophers in <code>#go-nuts</code> on the
|
|
||||||
<a href="https://freenode.net/">Freenode</a> IRC server.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The official mailing list for discussion of the Go language is
|
|
||||||
<a href="//groups.google.com/group/golang-nuts">Go Nuts</a>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Report bugs using the
|
|
||||||
<a href="//golang.org/issue">Go issue tracker</a>.
|
|
||||||
</p>
|
|
||||||
|
|
@ -34,6 +34,7 @@ We encourage all Go users to subscribe to
|
||||||
<p>A <a href="/doc/devel/release.html">summary</a> of the changes between Go releases. Notes for the major releases:</p>
|
<p>A <a href="/doc/devel/release.html">summary</a> of the changes between Go releases. Notes for the major releases:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
<li><a href="/doc/go1.13">Go 1.13</a> <small>(September 2019)</small></li>
|
||||||
<li><a href="/doc/go1.12">Go 1.12</a> <small>(February 2019)</small></li>
|
<li><a href="/doc/go1.12">Go 1.12</a> <small>(February 2019)</small></li>
|
||||||
<li><a href="/doc/go1.11">Go 1.11</a> <small>(August 2018)</small></li>
|
<li><a href="/doc/go1.11">Go 1.11</a> <small>(August 2018)</small></li>
|
||||||
<li><a href="/doc/go1.10">Go 1.10</a> <small>(February 2018)</small></li>
|
<li><a href="/doc/go1.10">Go 1.10</a> <small>(February 2018)</small></li>
|
||||||
|
|
@ -114,7 +115,7 @@ Community-related issues should be reported to
|
||||||
See the <a href="/conduct">Code of Conduct</a> for more details.
|
See the <a href="/conduct">Code of Conduct</a> for more details.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3><a href="/doc/contribute.html">Contributing code</a></h3>
|
<h3><a href="/doc/contribute.html">Contributing code & documentation</a></h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Go is an open source project and we welcome contributions from the community.
|
Go is an open source project and we welcome contributions from the community.
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,46 @@ in supported releases as needed by issuing minor revisions
|
||||||
(for example, Go 1.6.1, Go 1.6.2, and so on).
|
(for example, Go 1.6.1, Go 1.6.2, and so on).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h2 id="go1.13">go1.13 (released 2019/09/03)</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Go 1.13 is a major release of Go.
|
||||||
|
Read the <a href="/doc/go1.13">Go 1.13 Release Notes</a> for more information.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 id="go1.13.minor">Minor revisions</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
go1.13.1 (released 2019/09/25) includes security fixes to the
|
||||||
|
<code>net/http</code> and <code>net/textproto</code> packages.
|
||||||
|
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.13.1">Go
|
||||||
|
1.13.1 milestone</a> on our issue tracker for details.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
go1.13.2 (released 2019/10/17) includes security fixes to the
|
||||||
|
<code>crypto/dsa</code> package and the compiler.
|
||||||
|
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.13.2">Go
|
||||||
|
1.13.2 milestone</a> on our issue tracker for details.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
go1.13.3 (released 2019/10/17) includes fixes to the go command,
|
||||||
|
the toolchain, the runtime, <code>syscall</code>, <code>net</code>,
|
||||||
|
<code>net/http</code>, and <code>crypto/ecdsa</code> packages.
|
||||||
|
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.13.3">Go
|
||||||
|
1.13.3 milestone</a> on our issue tracker for details.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
go1.13.4 (released 2019/10/31) includes fixes to the <code>net/http</code> and
|
||||||
|
<code>syscall</code> packages. It also fixes an issue on macOS 10.15 Catalina
|
||||||
|
where the non-notarized installer and binaries were being
|
||||||
|
<a href="https://golang.org/issue/34986">rejected by Gatekeeper</a>.
|
||||||
|
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.13.4">Go
|
||||||
|
1.13.4 milestone</a> on our issue tracker for details.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2 id="go1.12">go1.12 (released 2019/02/25)</h2>
|
<h2 id="go1.12">go1.12 (released 2019/02/25)</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -98,6 +138,34 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.12.9+labe
|
||||||
1.12.9 milestone</a> on our issue tracker for details.
|
1.12.9 milestone</a> on our issue tracker for details.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
go1.12.10 (released 2019/09/25) includes security fixes to the
|
||||||
|
<code>net/http</code> and <code>net/textproto</code> packages.
|
||||||
|
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.12.10">Go
|
||||||
|
1.12.10 milestone</a> on our issue tracker for details.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
go1.12.11 (released 2019/10/17) includes security fixes to the
|
||||||
|
<code>crypto/dsa</code> package.
|
||||||
|
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.12.11">Go
|
||||||
|
1.12.11 milestone</a> on our issue tracker for details.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
go1.12.12 (released 2019/10/17) includes fixes to the go command,
|
||||||
|
runtime, <code>syscall</code> and <code>net</code> packages.
|
||||||
|
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.12.12">Go
|
||||||
|
1.12.12 milestone</a> on our issue tracker for details.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
go1.12.13 (released 2019/10/31) fixes an issue on macOS 10.15 Catalina
|
||||||
|
where the non-notarized installer and binaries were being
|
||||||
|
<a href="https://golang.org/issue/34986">rejected by Gatekeeper</a>.
|
||||||
|
Only macOS users who hit this issue need to update.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2 id="go1.11">go1.11 (released 2018/08/24)</h2>
|
<h2 id="go1.11">go1.11 (released 2018/08/24)</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
232
doc/docs.html
232
doc/docs.html
|
|
@ -1,232 +0,0 @@
|
||||||
<!--{
|
|
||||||
"Title": "Documentation",
|
|
||||||
"Path": "/doc/",
|
|
||||||
"Template": true
|
|
||||||
}-->
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The Go programming language is an open source project to make programmers more
|
|
||||||
productive.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Go is expressive, concise, clean, and efficient. Its concurrency
|
|
||||||
mechanisms make it easy to write programs that get the most out of multicore
|
|
||||||
and networked machines, while its novel type system enables flexible and
|
|
||||||
modular program construction. Go compiles quickly to machine code yet has the
|
|
||||||
convenience of garbage collection and the power of run-time reflection. It's a
|
|
||||||
fast, statically typed, compiled language that feels like a dynamically typed,
|
|
||||||
interpreted language.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div id="manual-nav"></div>
|
|
||||||
|
|
||||||
<h2>Installing Go</h2>
|
|
||||||
|
|
||||||
<h3><a href="/doc/install">Getting Started</a></h3>
|
|
||||||
<p>
|
|
||||||
Instructions for downloading and installing the Go compilers, tools, and
|
|
||||||
libraries.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h2 id="learning">Learning Go</h2>
|
|
||||||
|
|
||||||
<img class="gopher" src="/doc/gopher/doc.png"/>
|
|
||||||
|
|
||||||
<h3 id="go_tour">
|
|
||||||
{{if $.GoogleCN}}
|
|
||||||
A Tour of Go
|
|
||||||
{{else}}
|
|
||||||
<a href="//tour.golang.org/">A Tour of Go</a>
|
|
||||||
{{end}}
|
|
||||||
</h3>
|
|
||||||
<p>
|
|
||||||
An interactive introduction to Go in three sections.
|
|
||||||
The first section covers basic syntax and data structures; the second discusses
|
|
||||||
methods and interfaces; and the third introduces Go's concurrency primitives.
|
|
||||||
Each section concludes with a few exercises so you can practice what you've
|
|
||||||
learned. You can {{if not $.GoogleCN}}<a href="//tour.golang.org/">take the tour
|
|
||||||
online</a> or{{end}} install it locally with:
|
|
||||||
</p>
|
|
||||||
<pre>
|
|
||||||
$ go get golang.org/x/tour
|
|
||||||
</pre>
|
|
||||||
<p>
|
|
||||||
This will place the <code>tour</code> binary in your workspace's <code>bin</code> directory.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="code"><a href="code.html">How to write Go code</a></h3>
|
|
||||||
<p>
|
|
||||||
{{if not $.GoogleCN}}
|
|
||||||
Also available as a <a href="//www.youtube.com/watch?v=XCsL89YtqCs">screencast</a>, this
|
|
||||||
{{else}}
|
|
||||||
This
|
|
||||||
{{end}}
|
|
||||||
doc explains how to use the <a href="/cmd/go/">go command</a>
|
|
||||||
to fetch, build, and install packages, commands, and run tests.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="editors"><a href="editors.html">Editor plugins and IDEs</a></h3>
|
|
||||||
<p>
|
|
||||||
A document that summarizes commonly used editor plugins and IDEs with
|
|
||||||
Go support.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="effective_go"><a href="effective_go.html">Effective Go</a></h3>
|
|
||||||
<p>
|
|
||||||
A document that gives tips for writing clear, idiomatic Go code.
|
|
||||||
A must read for any new Go programmer. It augments the tour and
|
|
||||||
the language specification, both of which should be read first.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="diagnostics"><a href="/doc/diagnostics.html">Diagnostics</a></h3>
|
|
||||||
<p>
|
|
||||||
Summarizes tools and methodologies to diagnose problems in Go programs.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="faq"><a href="/doc/faq">Frequently Asked Questions (FAQ)</a></h3>
|
|
||||||
<p>
|
|
||||||
Answers to common questions about Go.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="wiki"><a href="/wiki">The Go Wiki</a></h3>
|
|
||||||
<p>A wiki maintained by the Go community.</p>
|
|
||||||
|
|
||||||
<h4 id="learn_more">More</h4>
|
|
||||||
<p>
|
|
||||||
See the <a href="/wiki/Learn">Learn</a> page at the <a href="/wiki">Wiki</a>
|
|
||||||
for more Go learning resources.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h2 id="references">References</h2>
|
|
||||||
|
|
||||||
<h3 id="pkg"><a href="/pkg/">Package Documentation</a></h3>
|
|
||||||
<p>
|
|
||||||
The documentation for the Go standard library.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="cmd"><a href="/doc/cmd">Command Documentation</a></h3>
|
|
||||||
<p>
|
|
||||||
The documentation for the Go tools.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="spec"><a href="/ref/spec">Language Specification</a></h3>
|
|
||||||
<p>
|
|
||||||
The official Go Language specification.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="go_mem"><a href="/ref/mem">The Go Memory Model</a></h3>
|
|
||||||
<p>
|
|
||||||
A document that specifies the conditions under which reads of a variable in
|
|
||||||
one goroutine can be guaranteed to observe values produced by writes to the
|
|
||||||
same variable in a different goroutine.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="release"><a href="/doc/devel/release.html">Release History</a></h3>
|
|
||||||
<p>A summary of the changes between Go releases.</p>
|
|
||||||
|
|
||||||
|
|
||||||
<h2 id="articles">Articles</h2>
|
|
||||||
|
|
||||||
{{if not $.GoogleCN}}
|
|
||||||
<h3 id="blog"><a href="//blog.golang.org/">The Go Blog</a></h3>
|
|
||||||
<p>The official blog of the Go project, featuring news and in-depth articles by
|
|
||||||
the Go team and guests.</p>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
<h4>Codewalks</h4>
|
|
||||||
<p>
|
|
||||||
Guided tours of Go programs.
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li><a href="/doc/codewalk/functions">First-Class Functions in Go</a></li>
|
|
||||||
<li><a href="/doc/codewalk/markov">Generating arbitrary text: a Markov chain algorithm</a></li>
|
|
||||||
<li><a href="/doc/codewalk/sharemem">Share Memory by Communicating</a></li>
|
|
||||||
<li><a href="/doc/articles/wiki/">Writing Web Applications</a> - building a simple web application.</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{{if not $.GoogleCN}}
|
|
||||||
<h4>Language</h4>
|
|
||||||
<ul>
|
|
||||||
<li><a href="/blog/json-rpc-tale-of-interfaces">JSON-RPC: a tale of interfaces</a></li>
|
|
||||||
<li><a href="/blog/gos-declaration-syntax">Go's Declaration Syntax</a></li>
|
|
||||||
<li><a href="/blog/defer-panic-and-recover">Defer, Panic, and Recover</a></li>
|
|
||||||
<li><a href="/blog/go-concurrency-patterns-timing-out-and">Go Concurrency Patterns: Timing out, moving on</a></li>
|
|
||||||
<li><a href="/blog/go-slices-usage-and-internals">Go Slices: usage and internals</a></li>
|
|
||||||
<li><a href="/blog/gif-decoder-exercise-in-go-interfaces">A GIF decoder: an exercise in Go interfaces</a></li>
|
|
||||||
<li><a href="/blog/error-handling-and-go">Error Handling and Go</a></li>
|
|
||||||
<li><a href="/blog/organizing-go-code">Organizing Go code</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h4>Packages</h4>
|
|
||||||
<ul>
|
|
||||||
<li><a href="/blog/json-and-go">JSON and Go</a> - using the <a href="/pkg/encoding/json/">json</a> package.</li>
|
|
||||||
<li><a href="/blog/gobs-of-data">Gobs of data</a> - the design and use of the <a href="/pkg/encoding/gob/">gob</a> package.</li>
|
|
||||||
<li><a href="/blog/laws-of-reflection">The Laws of Reflection</a> - the fundamentals of the <a href="/pkg/reflect/">reflect</a> package.</li>
|
|
||||||
<li><a href="/blog/go-image-package">The Go image package</a> - the fundamentals of the <a href="/pkg/image/">image</a> package.</li>
|
|
||||||
<li><a href="/blog/go-imagedraw-package">The Go image/draw package</a> - the fundamentals of the <a href="/pkg/image/draw/">image/draw</a> package.</li>
|
|
||||||
</ul>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
<h4>Tools</h4>
|
|
||||||
<ul>
|
|
||||||
<li><a href="/doc/articles/go_command.html">About the Go command</a> - why we wrote it, what it is, what it's not, and how to use it.</li>
|
|
||||||
<li><a href="/doc/gdb">Debugging Go Code with GDB</a></li>
|
|
||||||
<li><a href="/doc/articles/race_detector.html">Data Race Detector</a> - a manual for the data race detector.</li>
|
|
||||||
<li><a href="/doc/asm">A Quick Guide to Go's Assembler</a> - an introduction to the assembler used by Go.</li>
|
|
||||||
{{if not $.GoogleCN}}
|
|
||||||
<li><a href="/blog/c-go-cgo">C? Go? Cgo!</a> - linking against C code with <a href="/cmd/cgo/">cgo</a>.</li>
|
|
||||||
<li><a href="/blog/godoc-documenting-go-code">Godoc: documenting Go code</a> - writing good documentation for <a href="/cmd/godoc/">godoc</a>.</li>
|
|
||||||
<li><a href="/blog/profiling-go-programs">Profiling Go Programs</a></li>
|
|
||||||
<li><a href="/blog/race-detector">Introducing the Go Race Detector</a> - an introduction to the race detector.</li>
|
|
||||||
{{end}}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h4 id="articles_more">More</h4>
|
|
||||||
<p>
|
|
||||||
See the <a href="/wiki/Articles">Articles page</a> at the
|
|
||||||
<a href="/wiki">Wiki</a> for more Go articles.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{{if not $.GoogleCN}}
|
|
||||||
<h2 id="talks">Talks</h2>
|
|
||||||
|
|
||||||
<img class="gopher" src="/doc/gopher/talks.png"/>
|
|
||||||
|
|
||||||
<h3 id="video_tour_of_go"><a href="https://research.swtch.com/gotour">A Video Tour of Go</a></h3>
|
|
||||||
<p>
|
|
||||||
Three things that make Go fast, fun, and productive:
|
|
||||||
interfaces, reflection, and concurrency. Builds a toy web crawler to
|
|
||||||
demonstrate these.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="go_code_that_grows"><a href="//vimeo.com/53221560">Code that grows with grace</a></h3>
|
|
||||||
<p>
|
|
||||||
One of Go's key design goals is code adaptability; that it should be easy to take a simple design and build upon it in a clean and natural way. In this talk Andrew Gerrand describes a simple "chat roulette" server that matches pairs of incoming TCP connections, and then use Go's concurrency mechanisms, interfaces, and standard library to extend it with a web interface and other features. While the function of the program changes dramatically, Go's flexibility preserves the original design as it grows.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="go_concurrency_patterns"><a href="//www.youtube.com/watch?v=f6kdp27TYZs">Go Concurrency Patterns</a></h3>
|
|
||||||
<p>
|
|
||||||
Concurrency is the key to designing high performance network services. Go's concurrency primitives (goroutines and channels) provide a simple and efficient means of expressing concurrent execution. In this talk we see how tricky concurrency problems can be solved gracefully with simple Go code.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="advanced_go_concurrency_patterns"><a href="//www.youtube.com/watch?v=QDDwwePbDtw">Advanced Go Concurrency Patterns</a></h3>
|
|
||||||
<p>
|
|
||||||
This talk expands on the <i>Go Concurrency Patterns</i> talk to dive deeper into Go's concurrency primitives.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h4 id="talks_more">More</h4>
|
|
||||||
<p>
|
|
||||||
See the <a href="/talks">Go Talks site</a> and <a href="/wiki/GoTalks">wiki page</a> for more Go talks.
|
|
||||||
</p>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
<h2 id="nonenglish">Non-English Documentation</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
See the <a href="/wiki/NonEnglish">NonEnglish</a> page
|
|
||||||
at the <a href="/wiki">Wiki</a> for localized
|
|
||||||
documentation.
|
|
||||||
</p>
|
|
||||||
|
|
@ -624,7 +624,7 @@ if it has already been declared, provided:
|
||||||
<li>this declaration is in the same scope as the existing declaration of <code>v</code>
|
<li>this declaration is in the same scope as the existing declaration of <code>v</code>
|
||||||
(if <code>v</code> is already declared in an outer scope, the declaration will create a new variable §),</li>
|
(if <code>v</code> is already declared in an outer scope, the declaration will create a new variable §),</li>
|
||||||
<li>the corresponding value in the initialization is assignable to <code>v</code>, and</li>
|
<li>the corresponding value in the initialization is assignable to <code>v</code>, and</li>
|
||||||
<li>there is at least one other variable in the declaration that is being declared anew.</li>
|
<li>there is at least one other variable that is created by the declaration.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
This document explains how to use gccgo, a compiler for
|
This document explains how to use gccgo, a compiler for
|
||||||
the Go language. The gccgo compiler is a new frontend
|
the Go language. The gccgo compiler is a new frontend
|
||||||
for GCC, the widely used GNU compiler. Although the
|
for GCC, the widely used GNU compiler. Although the
|
||||||
frontend itself is under a BSD-style license, gccgo is
|
frontend itself is under a BSD-style license, gccgo is
|
||||||
normally used as part of GCC and is then covered by
|
normally used as part of GCC and is then covered by
|
||||||
the <a href="https://www.gnu.org/licenses/gpl.html">GNU General Public
|
the <a href="https://www.gnu.org/licenses/gpl.html">GNU General Public
|
||||||
|
|
@ -24,10 +24,10 @@ compiler.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The simplest way to install gccgo is to install a GCC binary release
|
The simplest way to install gccgo is to install a GCC binary release
|
||||||
built to include Go support. GCC binary releases are available from
|
built to include Go support. GCC binary releases are available from
|
||||||
<a href="https://gcc.gnu.org/install/binaries.html">various
|
<a href="https://gcc.gnu.org/install/binaries.html">various
|
||||||
websites</a> and are typically included as part of GNU/Linux
|
websites</a> and are typically included as part of GNU/Linux
|
||||||
distributions. We expect that most people who build these binaries
|
distributions. We expect that most people who build these binaries
|
||||||
will include Go support.
|
will include Go support.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -38,7 +38,7 @@ The GCC 4.7.1 release and all later 4.7 releases include a complete
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Due to timing, the GCC 4.8.0 and 4.8.1 releases are close to but not
|
Due to timing, the GCC 4.8.0 and 4.8.1 releases are close to but not
|
||||||
identical to Go 1.1. The GCC 4.8.2 release includes a complete Go
|
identical to Go 1.1. The GCC 4.8.2 release includes a complete Go
|
||||||
1.1.2 implementation.
|
1.1.2 implementation.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -48,28 +48,32 @@ The GCC 4.9 releases include a complete Go 1.2 implementation.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The GCC 5 releases include a complete implementation of the Go 1.4
|
The GCC 5 releases include a complete implementation of the Go 1.4
|
||||||
user libraries. The Go 1.4 runtime is not fully merged, but that
|
user libraries. The Go 1.4 runtime is not fully merged, but that
|
||||||
should not be visible to Go programs.
|
should not be visible to Go programs.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The GCC 6 releases include a complete implementation of the Go 1.6.1
|
The GCC 6 releases include a complete implementation of the Go 1.6.1
|
||||||
user libraries. The Go 1.6 runtime is not fully merged, but that
|
user libraries. The Go 1.6 runtime is not fully merged, but that
|
||||||
should not be visible to Go programs.
|
should not be visible to Go programs.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The GCC 7 releases include a complete implementation of the Go 1.8.1
|
The GCC 7 releases include a complete implementation of the Go 1.8.1
|
||||||
user libraries. As with earlier releases, the Go 1.8 runtime is not
|
user libraries. As with earlier releases, the Go 1.8 runtime is not
|
||||||
fully merged, but that should not be visible to Go programs.
|
fully merged, but that should not be visible to Go programs.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The GCC 8 releases are expected to include a complete implementation
|
The GCC 8 releases include a complete implementation of the Go 1.10.1
|
||||||
of the Go 1.10 release, depending on release timing. The Go 1.10
|
release. The Go 1.10 runtime has now been fully merged into the GCC
|
||||||
runtime has now been fully merged into the GCC development sources,
|
development sources, and concurrent garbage collection is fully
|
||||||
and concurrent garbage collection is expected to be fully supported in
|
supported.
|
||||||
GCC 8.
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The GCC 9 releases include a complete implementation of the Go 1.12.2
|
||||||
|
release.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2 id="Source_code">Source code</h2>
|
<h2 id="Source_code">Source code</h2>
|
||||||
|
|
@ -77,10 +81,10 @@ GCC 8.
|
||||||
<p>
|
<p>
|
||||||
If you cannot use a release, or prefer to build gccgo for
|
If you cannot use a release, or prefer to build gccgo for
|
||||||
yourself,
|
yourself,
|
||||||
the gccgo source code is accessible via Subversion. The
|
the gccgo source code is accessible via Subversion. The
|
||||||
GCC web site
|
GCC web site
|
||||||
has <a href="https://gcc.gnu.org/svn.html">instructions for getting the
|
has <a href="https://gcc.gnu.org/svn.html">instructions for getting the
|
||||||
GCC source code</a>. The gccgo source code is included. As a
|
GCC source code</a>. The gccgo source code is included. As a
|
||||||
convenience, a stable version of the Go support is available in
|
convenience, a stable version of the Go support is available in
|
||||||
a branch of the main GCC code
|
a branch of the main GCC code
|
||||||
repository: <code>svn://gcc.gnu.org/svn/gcc/branches/gccgo</code>.
|
repository: <code>svn://gcc.gnu.org/svn/gcc/branches/gccgo</code>.
|
||||||
|
|
@ -90,7 +94,7 @@ This branch is periodically updated with stable Go compiler sources.
|
||||||
<p>
|
<p>
|
||||||
Note that although <code>gcc.gnu.org</code> is the most convenient way
|
Note that although <code>gcc.gnu.org</code> is the most convenient way
|
||||||
to get the source code for the Go frontend, it is not where the master
|
to get the source code for the Go frontend, it is not where the master
|
||||||
sources live. If you want to contribute changes to the Go frontend
|
sources live. If you want to contribute changes to the Go frontend
|
||||||
compiler, see <a href="/doc/gccgo_contribute.html">Contributing to
|
compiler, see <a href="/doc/gccgo_contribute.html">Contributing to
|
||||||
gccgo</a>.
|
gccgo</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -100,16 +104,16 @@ gccgo</a>.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Building gccgo is just like building GCC
|
Building gccgo is just like building GCC
|
||||||
with one or two additional options. See
|
with one or two additional options. See
|
||||||
the <a href="https://gcc.gnu.org/install/">instructions on the gcc web
|
the <a href="https://gcc.gnu.org/install/">instructions on the gcc web
|
||||||
site</a>. When you run <code>configure</code>, add the
|
site</a>. When you run <code>configure</code>, add the
|
||||||
option <code>--enable-languages=c,c++,go</code> (along with other
|
option <code>--enable-languages=c,c++,go</code> (along with other
|
||||||
languages you may want to build). If you are targeting a 32-bit x86,
|
languages you may want to build). If you are targeting a 32-bit x86,
|
||||||
then you will want to build gccgo to default to
|
then you will want to build gccgo to default to
|
||||||
supporting locked compare and exchange instructions; do this by also
|
supporting locked compare and exchange instructions; do this by also
|
||||||
using the <code>configure</code> option <code>--with-arch=i586</code>
|
using the <code>configure</code> option <code>--with-arch=i586</code>
|
||||||
(or a newer architecture, depending on where you need your programs to
|
(or a newer architecture, depending on where you need your programs to
|
||||||
run). If you are targeting a 64-bit x86, but sometimes want to use
|
run). If you are targeting a 64-bit x86, but sometimes want to use
|
||||||
the <code>-m32</code> option, then use the <code>configure</code>
|
the <code>-m32</code> option, then use the <code>configure</code>
|
||||||
option <code>--with-arch-32=i586</code>.
|
option <code>--with-arch-32=i586</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -118,18 +122,18 @@ option <code>--with-arch-32=i586</code>.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
On x86 GNU/Linux systems the gccgo compiler is able to
|
On x86 GNU/Linux systems the gccgo compiler is able to
|
||||||
use a small discontiguous stack for goroutines. This permits programs
|
use a small discontiguous stack for goroutines. This permits programs
|
||||||
to run many more goroutines, since each goroutine can use a relatively
|
to run many more goroutines, since each goroutine can use a relatively
|
||||||
small stack. Doing this requires using the gold linker version 2.22
|
small stack. Doing this requires using the gold linker version 2.22
|
||||||
or later. You can either install GNU binutils 2.22 or later, or you
|
or later. You can either install GNU binutils 2.22 or later, or you
|
||||||
can build gold yourself.
|
can build gold yourself.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To build gold yourself, build the GNU binutils,
|
To build gold yourself, build the GNU binutils,
|
||||||
using <code>--enable-gold=default</code> when you run
|
using <code>--enable-gold=default</code> when you run
|
||||||
the <code>configure</code> script. Before building, you must install
|
the <code>configure</code> script. Before building, you must install
|
||||||
the flex and bison packages. A typical sequence would look like
|
the flex and bison packages. A typical sequence would look like
|
||||||
this (you can replace <code>/opt/gold</code> with any directory to
|
this (you can replace <code>/opt/gold</code> with any directory to
|
||||||
which you have write access):
|
which you have write access):
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -157,7 +161,7 @@ option <code>--with-ld=<var>GOLD_BINARY</var></code>.
|
||||||
A number of prerequisites are required to build GCC, as
|
A number of prerequisites are required to build GCC, as
|
||||||
described on
|
described on
|
||||||
the <a href="https://gcc.gnu.org/install/prerequisites.html">gcc web
|
the <a href="https://gcc.gnu.org/install/prerequisites.html">gcc web
|
||||||
site</a>. It is important to install all the prerequisites before
|
site</a>. It is important to install all the prerequisites before
|
||||||
running the gcc <code>configure</code> script.
|
running the gcc <code>configure</code> script.
|
||||||
The prerequisite libraries can be conveniently downloaded using the
|
The prerequisite libraries can be conveniently downloaded using the
|
||||||
script <code>contrib/download_prerequisites</code> in the GCC sources.
|
script <code>contrib/download_prerequisites</code> in the GCC sources.
|
||||||
|
|
@ -183,7 +187,7 @@ make install
|
||||||
<h2 id="Using_gccgo">Using gccgo</h2>
|
<h2 id="Using_gccgo">Using gccgo</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The gccgo compiler works like other gcc frontends. As of GCC 5 the gccgo
|
The gccgo compiler works like other gcc frontends. As of GCC 5 the gccgo
|
||||||
installation also includes a version of the <code>go</code> command,
|
installation also includes a version of the <code>go</code> command,
|
||||||
which may be used to build Go programs as described at
|
which may be used to build Go programs as described at
|
||||||
<a href="https://golang.org/cmd/go">https://golang.org/cmd/go</a>.
|
<a href="https://golang.org/cmd/go">https://golang.org/cmd/go</a>.
|
||||||
|
|
@ -208,7 +212,7 @@ gccgo -o file file.o
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
To run the resulting file, you will need to tell the program where to
|
To run the resulting file, you will need to tell the program where to
|
||||||
find the compiled Go packages. There are a few ways to do this:
|
find the compiled Go packages. There are a few ways to do this:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
|
@ -226,11 +230,11 @@ export LD_LIBRARY_PATH
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Here <code>${prefix}</code> is the <code>--prefix</code> option used
|
Here <code>${prefix}</code> is the <code>--prefix</code> option used
|
||||||
when building gccgo. For a binary install this is
|
when building gccgo. For a binary install this is
|
||||||
normally <code>/usr</code>. Whether to use <code>lib</code>
|
normally <code>/usr</code>. Whether to use <code>lib</code>
|
||||||
or <code>lib64</code> depends on the target.
|
or <code>lib64</code> depends on the target.
|
||||||
Typically <code>lib64</code> is correct for x86_64 systems,
|
Typically <code>lib64</code> is correct for x86_64 systems,
|
||||||
and <code>lib</code> is correct for other systems. The idea is to
|
and <code>lib</code> is correct for other systems. The idea is to
|
||||||
name the directory where <code>libgo.so</code> is found.
|
name the directory where <code>libgo.so</code> is found.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -325,9 +329,9 @@ objcopy -j .go_export FILE.o FILE.gox
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The gccgo compiler will look in the current
|
The gccgo compiler will look in the current
|
||||||
directory for import files. In more complex scenarios you
|
directory for import files. In more complex scenarios you
|
||||||
may pass the <code>-I</code> or <code>-L</code> option to
|
may pass the <code>-I</code> or <code>-L</code> option to
|
||||||
gccgo. Both options take directories to search. The
|
gccgo. Both options take directories to search. The
|
||||||
<code>-L</code> option is also passed to the linker.
|
<code>-L</code> option is also passed to the linker.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -348,11 +352,11 @@ gccgo -o main main.o mypackage.o # Explicitly links with mypackage.o
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
If you use the <code>-g</code> option when you compile, you can run
|
If you use the <code>-g</code> option when you compile, you can run
|
||||||
<code>gdb</code> on your executable. The debugger has only limited
|
<code>gdb</code> on your executable. The debugger has only limited
|
||||||
knowledge about Go. You can set breakpoints, single-step,
|
knowledge about Go. You can set breakpoints, single-step,
|
||||||
etc. You can print variables, but they will be printed as though they
|
etc. You can print variables, but they will be printed as though they
|
||||||
had C/C++ types. For numeric types this doesn't matter. Go strings
|
had C/C++ types. For numeric types this doesn't matter. Go strings
|
||||||
and interfaces will show up as two-element structures. Go
|
and interfaces will show up as two-element structures. Go
|
||||||
maps and channels are always represented as C pointers to run-time
|
maps and channels are always represented as C pointers to run-time
|
||||||
structures.
|
structures.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -399,7 +403,7 @@ assuming that the C pointer does point to 10 elements.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
A slice in Go is a structure. The current definition is
|
A slice in Go is a structure. The current definition is
|
||||||
(this is <b style="color: red;">subject to change</b>):
|
(this is <b style="color: red;">subject to change</b>):
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -413,15 +417,15 @@ struct __go_slice {
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The type of a Go function is a pointer to a struct (this is
|
The type of a Go function is a pointer to a struct (this is
|
||||||
<b style="color: red;">subject to change</b>). The first field in the
|
<b style="color: red;">subject to change</b>). The first field in the
|
||||||
struct points to the code of the function, which will be equivalent to
|
struct points to the code of the function, which will be equivalent to
|
||||||
a pointer to a C function whose parameter types are equivalent, with
|
a pointer to a C function whose parameter types are equivalent, with
|
||||||
an additional trailing parameter. The trailing parameter is the
|
an additional trailing parameter. The trailing parameter is the
|
||||||
closure, and the argument to pass is a pointer to the Go function
|
closure, and the argument to pass is a pointer to the Go function
|
||||||
struct.
|
struct.
|
||||||
|
|
||||||
When a Go function returns more than one value, the C function returns
|
When a Go function returns more than one value, the C function returns
|
||||||
a struct. For example, these functions are roughly equivalent:
|
a struct. For example, these functions are roughly equivalent:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
|
@ -458,7 +462,7 @@ pointer while the C function is still using it.
|
||||||
<p>
|
<p>
|
||||||
Go code can call C functions directly using a Go extension implemented
|
Go code can call C functions directly using a Go extension implemented
|
||||||
in gccgo: a function declaration may be preceded by
|
in gccgo: a function declaration may be preceded by
|
||||||
<code>//extern NAME</code>. For example, here is how the C function
|
<code>//extern NAME</code>. For example, here is how the C function
|
||||||
<code>open</code> can be declared in Go:
|
<code>open</code> can be declared in Go:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -518,11 +522,11 @@ the <code>-gccgo</code> option instead.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Compile your C code as usual, and add the option
|
Compile your C code as usual, and add the option
|
||||||
<code>-fdump-go-spec=<var>FILENAME</var></code>. This will create the
|
<code>-fdump-go-spec=<var>FILENAME</var></code>. This will create the
|
||||||
file <code><var>FILENAME</var></code> as a side effect of the
|
file <code><var>FILENAME</var></code> as a side effect of the
|
||||||
compilation. This file will contain Go declarations for the types,
|
compilation. This file will contain Go declarations for the types,
|
||||||
variables and functions declared in the C code. C types that can not
|
variables and functions declared in the C code. C types that can not
|
||||||
be represented in Go will be recorded as comments in the Go code. The
|
be represented in Go will be recorded as comments in the Go code. The
|
||||||
generated file will not have a <code>package</code> declaration, but
|
generated file will not have a <code>package</code> declaration, but
|
||||||
can otherwise be compiled directly by gccgo.
|
can otherwise be compiled directly by gccgo.
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,13 @@ Do not send CLs removing the interior tags from such phrases.
|
||||||
main ul li { margin: 0.5em 0; }
|
main ul li { margin: 0.5em 0; }
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<h2 id="introduction">DRAFT RELEASE NOTES - Introduction to Go 1.13</h2>
|
<h2 id="introduction">Introduction to Go 1.13</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<strong>
|
The latest Go release, version 1.13, arrives six months after <a href="go1.12">Go 1.12</a>.
|
||||||
Go 1.13 is not yet released. These are work-in-progress
|
Most of its changes are in the implementation of the toolchain, runtime, and libraries.
|
||||||
release notes. Go 1.13 is expected to be released in August 2019.
|
As always, the release maintains the Go 1 <a href="/doc/go1compat.html">promise of compatibility</a>.
|
||||||
</strong>
|
We expect almost all Go programs to continue to compile and run as before.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -102,7 +102,7 @@ Do not send CLs removing the interior tags from such phrases.
|
||||||
|
|
||||||
<h2 id="ports">Ports</h2>
|
<h2 id="ports">Ports</h2>
|
||||||
|
|
||||||
<p>
|
<p id="nacl">
|
||||||
Go 1.13 is the last release that will run on Native Client (NaCl).
|
Go 1.13 is the last release that will run on Native Client (NaCl).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -122,7 +122,7 @@ Do not send CLs removing the interior tags from such phrases.
|
||||||
<h3 id="android">Android</h3>
|
<h3 id="android">Android</h3>
|
||||||
|
|
||||||
<p><!-- CL 170127 -->
|
<p><!-- CL 170127 -->
|
||||||
Go programs are now compatible with Android Q.
|
Go programs are now compatible with Android 10.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3 id="darwin">Darwin</h3>
|
<h3 id="darwin">Darwin</h3>
|
||||||
|
|
@ -139,7 +139,8 @@ Do not send CLs removing the interior tags from such phrases.
|
||||||
As <a href="go1.12#freebsd">announced</a> in the Go 1.12 release notes,
|
As <a href="go1.12#freebsd">announced</a> in the Go 1.12 release notes,
|
||||||
Go 1.13 now requires FreeBSD 11.2 or later;
|
Go 1.13 now requires FreeBSD 11.2 or later;
|
||||||
support for previous versions has been discontinued.
|
support for previous versions has been discontinued.
|
||||||
FreeBSD 12.0 or later requires a kernel with the COMPAT_FREEBSD11 option set (this is the default).
|
FreeBSD 12.0 or later requires a kernel with the <code>COMPAT_FREEBSD11</code>
|
||||||
|
option set (this is the default).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3 id="illumos">Illumos</h3>
|
<h3 id="illumos">Illumos</h3>
|
||||||
|
|
@ -150,18 +151,6 @@ Do not send CLs removing the interior tags from such phrases.
|
||||||
build tag.
|
build tag.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3 id="netbsd">NetBSD</h3>
|
|
||||||
|
|
||||||
<p><!--CL 155739 -->
|
|
||||||
Go now supports NetBSD on arm64.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="openbsd">OpenBSD</h3>
|
|
||||||
|
|
||||||
<p><!--CL 174125 -->
|
|
||||||
Go now supports OpenBSD on arm64.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3 id="windows">Windows</h3>
|
<h3 id="windows">Windows</h3>
|
||||||
|
|
||||||
<p><!-- CL 178977 -->
|
<p><!-- CL 178977 -->
|
||||||
|
|
@ -781,7 +770,7 @@ godoc
|
||||||
<dl id="net"><dt><a href="/pkg/net/">net</a></dt>
|
<dl id="net"><dt><a href="/pkg/net/">net</a></dt>
|
||||||
<dd>
|
<dd>
|
||||||
<p><!-- CL 156366 -->
|
<p><!-- CL 156366 -->
|
||||||
On Unix systems where <code>use-vc</code> is set in <code>resolve.conf</code>, TCP is used for DNS resolution.
|
On Unix systems where <code>use-vc</code> is set in <code>resolv.conf</code>, TCP is used for DNS resolution.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p><!-- CL 170678 -->
|
<p><!-- CL 170678 -->
|
||||||
|
|
@ -825,13 +814,14 @@ godoc
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p><!-- CL 140357 -->
|
<p><!-- CL 140357 -->
|
||||||
When reusing HTTP/2, the <a href="/pkg/net/http/#Transport"><code>Transport</code></a> no longer performs unnecessary TLS handshakes.
|
<a href="/pkg/net/http/#Transport.MaxConnsPerHost"><code>Transport.MaxConnsPerHost</code></a> now works
|
||||||
|
properly with HTTP/2.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p><!-- CL 154383 -->
|
<p><!-- CL 154383 -->
|
||||||
<a href="/pkg/net/http/#TimeoutHandler"><code>TimeoutHandler</code></a>'s
|
<a href="/pkg/net/http/#TimeoutHandler"><code>TimeoutHandler</code></a>'s
|
||||||
<a href="/pkg/net/http/#ResponseWriter"><code>ResponseWriter</code></a> now implements the
|
<a href="/pkg/net/http/#ResponseWriter"><code>ResponseWriter</code></a> now implements the
|
||||||
<a href="/pkg/net/http/#Pusher"><code>Pusher</code></a> and <a href="/pkg/net/http/#Flusher"><code>Flusher</code></a> interfaces.
|
<a href="/pkg/net/http/#Pusher"><code>Pusher</code></a> interface.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p><!-- CL 157339 -->
|
<p><!-- CL 157339 -->
|
||||||
|
|
@ -872,7 +862,8 @@ godoc
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p><!-- CL 179457 -->
|
<p><!-- CL 179457 -->
|
||||||
<a href="/pkg/net/http/#Transport"><code>Transport</code></a> now silently ignores a <code>408 "Request Timeout"</code> response.
|
The <a href="/pkg/net/http/#Transport"><code>Transport</code></a> no longer logs errors when servers
|
||||||
|
gracefully shut down idle connections using a <code>"408 Request Timeout"</code> response.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
</dl><!-- net/http -->
|
</dl><!-- net/http -->
|
||||||
|
|
@ -997,9 +988,10 @@ godoc
|
||||||
<dl id="syscall/js"><dt><a href="/pkg/syscall/js/">syscall/js</a></dt>
|
<dl id="syscall/js"><dt><a href="/pkg/syscall/js/">syscall/js</a></dt>
|
||||||
<dd>
|
<dd>
|
||||||
<p><!-- CL 177537 -->
|
<p><!-- CL 177537 -->
|
||||||
TypedArrayOf has been replaced by
|
<code>TypedArrayOf</code> has been replaced by
|
||||||
<a href="/pkg/syscall/js/#CopyBytesToGo"><code>CopyBytesToGo</code></a> and
|
<a href="/pkg/syscall/js/#CopyBytesToGo"><code>CopyBytesToGo</code></a> and
|
||||||
<a href="/pkg/syscall/js/#CopyBytesToJS"><code>CopyBytesToJS</code></a> for copying bytes between a byte slice and a Uint8Array.
|
<a href="/pkg/syscall/js/#CopyBytesToJS"><code>CopyBytesToJS</code></a> for copying bytes
|
||||||
|
between a byte slice and a <code>Uint8Array</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
</dl><!-- syscall/js -->
|
</dl><!-- syscall/js -->
|
||||||
|
|
|
||||||
290
doc/go1.14.html
Normal file
290
doc/go1.14.html
Normal file
|
|
@ -0,0 +1,290 @@
|
||||||
|
<!--{
|
||||||
|
"Title": "Go 1.14 Release Notes",
|
||||||
|
"Path": "/doc/go1.14",
|
||||||
|
"Template": true
|
||||||
|
}-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
NOTE: In this document and others in this directory, the convention is to
|
||||||
|
set fixed-width phrases with non-fixed-width spaces, as in
|
||||||
|
<code>hello</code> <code>world</code>.
|
||||||
|
Do not send CLs removing the interior tags from such phrases.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<style>
|
||||||
|
main ul li { margin: 0.5em 0; }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<h2 id="introduction">DRAFT RELEASE NOTES — Introduction to Go 1.14</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>
|
||||||
|
Go 1.14 is not yet released. These are work-in-progress
|
||||||
|
release notes. Go 1.14 is expected to be released in February 2020.
|
||||||
|
</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 id="language">Changes to the language</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
TODO
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 id="ports">Ports</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
TODO: is Dragonfly passing? On both Dragonfly release & tip? (ABI
|
||||||
|
change happened) Does the net package's interface APIs work on both?
|
||||||
|
https://golang.org/issue/34368.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
TODO: is Illumos up with a builder and passing?
|
||||||
|
https://golang.org/issue/15581.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
TODO: announce something about the Go Solaris port? Solaris itself
|
||||||
|
is unmaintained? The builder is still running at Oracle, but the
|
||||||
|
employee who set it up left the company and we have no way to
|
||||||
|
maintain it.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 id="darwin">Darwin</h3>
|
||||||
|
|
||||||
|
<p><!-- golang.org/issue/34749 -->
|
||||||
|
Go 1.14 is the last Go release to support 32-bit binaries on
|
||||||
|
macOS (the <code>darwin/386</code> port). They are no longer
|
||||||
|
supported by macOS, starting with macOS 10.15 (Catalina).
|
||||||
|
Go continues to support the 64-bit <code>darwin/amd64</code> port.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><!-- golang.org/issue/34751 -->
|
||||||
|
Go 1.14 will likely be the last Go release to support 32-bit
|
||||||
|
binaries on iOS, iPadOS, watchOS, and tvOS
|
||||||
|
(the <code>darwin/arm</code> port). Go continues to support the
|
||||||
|
64-bit <code>darwin/arm64</code> port.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 id="nacl">Native Client (NaCl)</h3>
|
||||||
|
|
||||||
|
<p><!-- golang.org/issue/30439 -->
|
||||||
|
As <a href="go1.13#ports">announced</a> in the Go 1.13 release notes,
|
||||||
|
Go 1.14 drops support for the Native Client platform (<code>GOOS=nacl</code>).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 id="tools">Tools</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
TODO
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 id="go-command">Go command</h3>
|
||||||
|
|
||||||
|
<h4 id="vendor">Vendoring</h4>
|
||||||
|
<!-- golang.org/issue/33848 -->
|
||||||
|
|
||||||
|
<p>
|
||||||
|
When the main module contains a top-level <code>vendor</code> directory and
|
||||||
|
its <code>go.mod</code> file specifies <code>go</code> <code>1.14</code> or
|
||||||
|
higher, the <code>go</code> command now defaults to <code>-mod=vendor</code>
|
||||||
|
for operations that accept that flag. A new value for that flag,
|
||||||
|
<code>-mod=mod</code>, causes the <code>go</code> command to instead load
|
||||||
|
modules from the module cache (as when no <code>vendor</code> directory is
|
||||||
|
present).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
When <code>-mod=vendor</code> is set (explicitly or by default), the
|
||||||
|
<code>go</code> command now verifies that the main module's
|
||||||
|
<code>vendor/modules.txt</code> file is consistent with its
|
||||||
|
<code>go.mod</code> file.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<code>go</code> <code>list</code> <code>-m</code> no longer silently omits
|
||||||
|
transitive dependencies that do not provide packages in
|
||||||
|
the <code>vendor</code> directory. It now fails explicitly if
|
||||||
|
<code>-mod=vendor</code> is set.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h4 id="go-flags">Flags</h4>
|
||||||
|
|
||||||
|
<p><!-- golang.org/issue/32502, golang.org/issue/30345 -->
|
||||||
|
The <code>go</code> <code>get</code> command no longer accepts
|
||||||
|
the <code>-mod</code> flag. Previously, the flag's setting either
|
||||||
|
<a href="https://golang.org/issue/30345">was ignored</a> or
|
||||||
|
<a href="https://golang.org/issue/32502">caused the build to fail</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><!-- golang.org/issue/31481 -->
|
||||||
|
<code>-modcacherw</code> is a new flag that instructs the <code>go</code>
|
||||||
|
command to leave newly-created directories in the module cache at their
|
||||||
|
default permissions rather than making them read-only.
|
||||||
|
The use of this flag makes it more likely that tests or other tools will
|
||||||
|
accidentally add files not included in the module's verified checksum.
|
||||||
|
However, it allows the use of <code>rm</code> <code>-rf</code>
|
||||||
|
(instead of <code>go</code> <code>clean</code> <code>-modcache</code>)
|
||||||
|
to remove the module cache.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><!-- golang.org/issue/34506 -->
|
||||||
|
<code>-modfile=file</code> is a new flag that instructs the <code>go</code>
|
||||||
|
command to read (and possibly write) an alternate go.mod file instead of the
|
||||||
|
one in the module root directory. A file named "go.mod" must still be present
|
||||||
|
in order to determine the module root directory, but it is not
|
||||||
|
accessed. When <code>-modfile</code> is specified, an alternate go.sum file
|
||||||
|
is also used: its path is derived from the <code>-modfile</code> flag by
|
||||||
|
trimming the ".mod" extension and appending ".sum".
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h4 id="incompatible-versions"><code>+incompatible</code> versions</h4>
|
||||||
|
<!-- golang.org/issue/34165 -->
|
||||||
|
|
||||||
|
<p>
|
||||||
|
If the latest version of a module contains a <code>go.mod</code> file,
|
||||||
|
<code>go</code> <code>get</code> will no longer upgrade to an
|
||||||
|
<a href="/cmd/go/#hdr-Module_compatibility_and_semantic_versioning">incompatible</a>
|
||||||
|
major version of that module unless such a version is requested explicitly
|
||||||
|
or is already required.
|
||||||
|
<code>go</code> <code>list</code> also omits incompatible major versions
|
||||||
|
for such a module when fetching directly from version control, but may
|
||||||
|
include them if reported by a proxy.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h4 id="module-downloading">Module downloading</h4>
|
||||||
|
|
||||||
|
<p><!-- golang.org/issue/26092 -->
|
||||||
|
The <code>go</code> command now supports Subversion repositories in module mode.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><!-- golang.org/issue/30748 -->
|
||||||
|
The <code>go</code> command now includes snippets of plain-text error messages
|
||||||
|
from module proxies and other HTTP servers.
|
||||||
|
An error message will only be shown if it is valid UTF-8 and consists of only
|
||||||
|
graphic characters and spaces.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 id="runtime">Runtime</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
TODO
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="library">Core library</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
TODO
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<dl id="bytes/hash"><dt><a href="/pkg/bytes/hash/">bytes/hash</a></dt>
|
||||||
|
<dd>
|
||||||
|
<p><!-- CL 186877 -->
|
||||||
|
TODO: <a href="https://golang.org/cl/186877">https://golang.org/cl/186877</a>: add hashing package for bytes and strings
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</dl><!-- bytes/hash -->
|
||||||
|
|
||||||
|
<dl id="crypto/tls"><dt><a href="/pkg/crypto/tls/">crypto/tls</a></dt>
|
||||||
|
<dd>
|
||||||
|
<p><!-- CL 191976 -->
|
||||||
|
TODO: <a href="https://golang.org/cl/191976">https://golang.org/cl/191976</a>: remove SSLv3 support
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><!-- CL 191999 -->
|
||||||
|
TODO: <a href="https://golang.org/cl/191999">https://golang.org/cl/191999</a>: remove TLS 1.3 opt-out
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><!-- CL 174329 -->
|
||||||
|
The <code>tls</code> package no longer supports NPN and now only
|
||||||
|
supports ALPN. In previous releases it supported both. There are
|
||||||
|
no API changes and code should function identically as before.
|
||||||
|
Most other clients & servers have already removed NPN support in
|
||||||
|
favor of the standardized ALPN.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</dl><!-- crypto/tls -->
|
||||||
|
|
||||||
|
<dl id="encoding/asn1"><dt><a href="/pkg/encoding/asn1/">encoding/asn1</a></dt>
|
||||||
|
<dd>
|
||||||
|
<p><!-- CL 126624 -->
|
||||||
|
TODO: <a href="https://golang.org/cl/126624">https://golang.org/cl/126624</a>: handle ASN1's string type BMPString
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</dl><!-- encoding/asn1 -->
|
||||||
|
|
||||||
|
<dl id="mime"><dt><a href="/pkg/mime/">mime</a></dt>
|
||||||
|
<dd>
|
||||||
|
<p><!-- CL 186927 -->
|
||||||
|
TODO: <a href="https://golang.org/cl/186927">https://golang.org/cl/186927</a>: update type of .js and .mjs files to text/javascript
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</dl><!-- mime -->
|
||||||
|
|
||||||
|
<dl id="math"><dt><a href="/pkg/math/">math</a></dt>
|
||||||
|
<dd>
|
||||||
|
<p><!-- CL 127458 -->
|
||||||
|
The new <a href="/pkg/math/#FMA"><code>FMA</code></a> function
|
||||||
|
computes <code>x*y+z</code> in floating point with no
|
||||||
|
intermediate rounding of the <code>x*y</code>
|
||||||
|
computation. Several architectures implement this computation
|
||||||
|
using dedicated hardware instructions for additional performance.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</dl><!-- math -->
|
||||||
|
|
||||||
|
<dl id="plugin"><dt><a href="/pkg/plugin/">plugin</a></dt>
|
||||||
|
<dd>
|
||||||
|
<p><!-- CL 191617 -->
|
||||||
|
TODO: <a href="https://golang.org/cl/191617">https://golang.org/cl/191617</a>: add freebsd/amd64 plugin support
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</dl><!-- plugin -->
|
||||||
|
|
||||||
|
<dl id="reflect">
|
||||||
|
|
||||||
|
<dt><a href="/pkg/reflect/">reflect</a></dt>
|
||||||
|
<dd>
|
||||||
|
<p><!-- CL 85661 -->
|
||||||
|
<a href="/pkg/reflect#StructOf"><code>StructOf</code></a> now
|
||||||
|
supports creating struct types with unexported fields, by
|
||||||
|
setting the <code>PkgPath</code> field in
|
||||||
|
a <code>StructField</code> element.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</dl><!-- reflect -->
|
||||||
|
|
||||||
|
<dl id="runtime"><dt><a href="/pkg/runtime/">runtime</a></dt>
|
||||||
|
<dd>
|
||||||
|
<p><!-- CL 187739 -->
|
||||||
|
TODO: <a href="https://golang.org/cl/187739">https://golang.org/cl/187739</a>: treat CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, CTRL_SHUTDOWN_EVENT as SIGTERM on Windows
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><!-- CL 188297 -->
|
||||||
|
TODO: <a href="https://golang.org/cl/188297">https://golang.org/cl/188297</a>: don't forward SIGPIPE on macOS
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</dl><!-- runtime -->
|
||||||
|
|
||||||
|
<dl id="testing"><dt><a href="/pkg/testing/">testing</a></dt>
|
||||||
|
<dd>
|
||||||
|
<p><!-- CL 201359 -->
|
||||||
|
The testing package now supports cleanup functions, called after
|
||||||
|
a test or benchmark has finished, by calling
|
||||||
|
<a href="/pkg/testing#T.Cleanup"><code>T.Cleanup</code></a> or
|
||||||
|
<a href="/pkg/testing#B.Cleanup"><code>B.Cleanup</code></a> respectively.
|
||||||
|
</p>
|
||||||
|
</dl><!-- testing -->
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
TODO
|
||||||
|
</p>
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<!--{
|
<!--{
|
||||||
"Title": "The Go Programming Language Specification",
|
"Title": "The Go Programming Language Specification",
|
||||||
"Subtitle": "Version of Aug 26, 2019",
|
"Subtitle": "Version of Sep 4, 2019",
|
||||||
"Path": "/ref/spec"
|
"Path": "/ref/spec"
|
||||||
}-->
|
}-->
|
||||||
|
|
||||||
|
|
@ -3732,7 +3732,7 @@ be replaced by a bitwise AND operation:
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The shift operators shift the left operand by the shift count specified by the
|
The shift operators shift the left operand by the shift count specified by the
|
||||||
right operand, which must be positive. If the shift count is negative at run time,
|
right operand, which must be non-negative. If the shift count is negative at run time,
|
||||||
a <a href="#Run_time_panics">run-time panic</a> occurs.
|
a <a href="#Run_time_panics">run-time panic</a> occurs.
|
||||||
The shift operators implement arithmetic shifts if the left operand is a signed
|
The shift operators implement arithmetic shifts if the left operand is a signed
|
||||||
integer and logical shifts if it is an unsigned integer.
|
integer and logical shifts if it is an unsigned integer.
|
||||||
|
|
|
||||||
|
|
@ -33,80 +33,64 @@ compiler using the GCC back end, see
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The Go compilers support nine instruction sets.
|
The Go compilers support twelve instruction sets:
|
||||||
There are important differences in the quality of the compilers for the different
|
|
||||||
architectures.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
<dt>
|
<dt>
|
||||||
<code>amd64</code> (also known as <code>x86-64</code>)
|
<code>amd64</code>, <code>386</code>
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
A mature implementation.
|
The <code>x86</code> instruction set, 64- and 32-bit.
|
||||||
</dd>
|
</dd>
|
||||||
<dt>
|
<dt>
|
||||||
<code>386</code> (<code>x86</code> or <code>x86-32</code>)
|
<code>arm64</code>, <code>arm</code>
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
Comparable to the <code>amd64</code> port.
|
The <code>ARM</code> instruction set, 64-bit (<code>AArch64</code>) and 32-bit.
|
||||||
</dd>
|
</dd>
|
||||||
<dt>
|
<dt>
|
||||||
<code>arm</code> (<code>ARM</code>)
|
<code>ppc64</code>, <code>ppc64le</code>
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
Supports Linux, FreeBSD, NetBSD, OpenBSD and Darwin binaries. Less widely used than the other ports.
|
The 64-bit PowerPC instruction set, big- and little-endian.
|
||||||
</dd>
|
</dd>
|
||||||
<dt>
|
<dt>
|
||||||
<code>arm64</code> (<code>AArch64</code>)
|
<code>s390x</code>
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
Supports Linux and Darwin binaries. New in 1.5 and not as well exercised as other ports.
|
The IBM z/Architecture.
|
||||||
</dd>
|
</dd>
|
||||||
<dt>
|
<dt>
|
||||||
<code>ppc64, ppc64le</code> (64-bit PowerPC big- and little-endian)
|
<code>mips64</code>, <code>mips64le</code>, <code>mips</code>, <code>mipsle</code>
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
Supports Linux binaries. New in 1.5 and not as well exercised as other ports.
|
The <code>MIPS</code> instruction set, big- and little-endian, 64- and 32-bit.
|
||||||
</dd>
|
</dd>
|
||||||
<dt>
|
<dt>
|
||||||
<code>mips, mipsle</code> (32-bit MIPS big- and little-endian)
|
<code>wasm</code>
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
Supports Linux binaries. New in 1.8 and not as well exercised as other ports.
|
<a href="https://webassembly.org">WebAssembly</a>.
|
||||||
</dd>
|
|
||||||
<dt>
|
|
||||||
<code>mips64, mips64le</code> (64-bit MIPS big- and little-endian)
|
|
||||||
</dt>
|
|
||||||
<dd>
|
|
||||||
Supports Linux binaries. New in 1.6 and not as well exercised as other ports.
|
|
||||||
</dd>
|
|
||||||
<dt>
|
|
||||||
<code>s390x</code> (IBM System z)
|
|
||||||
</dt>
|
|
||||||
<dd>
|
|
||||||
Supports Linux binaries. New in 1.7 and not as well exercised as other ports.
|
|
||||||
</dd>
|
|
||||||
<dt>
|
|
||||||
<code>wasm</code> (WebAssembly)
|
|
||||||
</dt>
|
|
||||||
<dd>
|
|
||||||
Targets the WebAssembly platform. New in 1.11 and not as well exercised as other ports.
|
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<p>
|
|
||||||
Except for things like low-level operating system interface code, the run-time
|
|
||||||
support is the same in all ports and includes a mark-and-sweep garbage
|
|
||||||
collector, efficient array and string slicing, and support for efficient
|
|
||||||
goroutines, such as stacks that grow and shrink on demand.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The compilers can target the DragonFly BSD, FreeBSD, Linux, NetBSD, OpenBSD,
|
The compilers can target the AIX, Android, DragonFly BSD, FreeBSD,
|
||||||
macOS (Darwin), Plan 9, Solaris and Windows operating systems.
|
Illumos, Linux, macOS/iOS (Darwin), NetBSD, OpenBSD, Plan 9, Solaris,
|
||||||
The full set of supported combinations is listed in the discussion of
|
and Windows operating systems (although not all operating systems
|
||||||
<a href="#environment">environment variables</a> below.
|
support all architectures).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
A list of ports which are considered "first class" is available at the
|
||||||
|
<a href="/wiki/PortingPolicy#first-class-ports">first class ports</a>
|
||||||
|
wiki page.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The full set of supported combinations is listed in the
|
||||||
|
discussion of <a href="#environment">environment variables</a> below.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
61
doc/modules.md
Normal file
61
doc/modules.md
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
<!--{
|
||||||
|
"Title": "Go Modules Reference",
|
||||||
|
"Subtitle": "Version of Sep 4, 2019",
|
||||||
|
"Path": "/ref/modules"
|
||||||
|
}-->
|
||||||
|
<!-- TODO(jayconrod): ensure golang.org/x/website can render Markdown or convert
|
||||||
|
this document to HTML before Go 1.14. -->
|
||||||
|
<!-- TODO(jayconrod): ensure Markdown renderer adds anchors or add them
|
||||||
|
manually. -->
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
## Glossary
|
||||||
|
|
||||||
|
## Packages, modules, and versions
|
||||||
|
|
||||||
|
## go.mod files
|
||||||
|
|
||||||
|
### go.mod file format
|
||||||
|
|
||||||
|
### Minimal version selection (MVS)
|
||||||
|
|
||||||
|
### Compatibility with non-module repositories
|
||||||
|
|
||||||
|
## Module-aware build commands
|
||||||
|
|
||||||
|
### Enabling modules
|
||||||
|
|
||||||
|
### Initializing modules
|
||||||
|
|
||||||
|
### Build commands
|
||||||
|
|
||||||
|
### Vendoring
|
||||||
|
|
||||||
|
### `go mod download`
|
||||||
|
|
||||||
|
### `go mod verify`
|
||||||
|
|
||||||
|
### `go mod edit`
|
||||||
|
|
||||||
|
### `go clean -modcache`
|
||||||
|
|
||||||
|
### Module commands outside a module
|
||||||
|
|
||||||
|
## Retrieving modules
|
||||||
|
|
||||||
|
### GOPROXY protocol
|
||||||
|
|
||||||
|
### Module zip requirements
|
||||||
|
|
||||||
|
### Privacy
|
||||||
|
|
||||||
|
### Private modules
|
||||||
|
|
||||||
|
## Authenticating modules
|
||||||
|
|
||||||
|
### go.sum file format
|
||||||
|
|
||||||
|
### Checksum database
|
||||||
|
|
||||||
|
### Privacy
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
// You can edit this code!
|
||||||
|
// Click here and start typing.
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,9 @@ const templateStr = `
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
{{end}}
|
{{end}}
|
||||||
<form action="/" name=f method="GET"><input maxLength=1024 size=70
|
<form action="/" name=f method="GET">
|
||||||
name=s value="" title="Text to QR Encode"><input type=submit
|
<input maxLength=1024 size=70 name=s value="" title="Text to QR Encode">
|
||||||
value="Show QR" name=qr>
|
<input type=submit value="Show QR" name=qr>
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,11 @@ For critical problems, you can encrypt your report using our PGP key (listed bel
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Please use a descriptive subject line for your report email.
|
To ensure your report is not marked as spam, please include the word "vulnerability"
|
||||||
|
anywhere in your email. Please use a descriptive subject line for your report email.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
After the initial reply to your report, the security team will endeavor to keep
|
After the initial reply to your report, the security team will endeavor to keep
|
||||||
you informed of the progress being made towards a fix and full announcement.
|
you informed of the progress being made towards a fix and full announcement.
|
||||||
These updates will be sent at least every five days.
|
These updates will be sent at least every five days.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo 'misc/benchcmp has moved:' >&2
|
|
||||||
echo ' go get -u golang.org/x/tools/cmd/benchcmp' >&2
|
|
||||||
exit 2
|
|
||||||
|
|
@ -52,7 +52,7 @@ func overlayDir(dstRoot, srcRoot string) error {
|
||||||
// Always copy directories (don't symlink them).
|
// Always copy directories (don't symlink them).
|
||||||
// If we add a file in the overlay, we don't want to add it in the original.
|
// If we add a file in the overlay, we don't want to add it in the original.
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
return os.Mkdir(dstPath, perm)
|
return os.Mkdir(dstPath, perm|0200)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the OS supports symlinks, use them instead of copying bytes.
|
// If the OS supports symlinks, use them instead of copying bytes.
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ func overlayDir(dstRoot, srcRoot string) error {
|
||||||
// Always copy directories (don't symlink them).
|
// Always copy directories (don't symlink them).
|
||||||
// If we add a file in the overlay, we don't want to add it in the original.
|
// If we add a file in the overlay, we don't want to add it in the original.
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
return os.Mkdir(dstPath, perm)
|
return os.Mkdir(dstPath, perm|0200)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the OS supports symlinks, use them instead of copying bytes.
|
// If the OS supports symlinks, use them instead of copying bytes.
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ func Test27660(t *testing.T) { test27660(t) }
|
||||||
func Test28896(t *testing.T) { test28896(t) }
|
func Test28896(t *testing.T) { test28896(t) }
|
||||||
func Test30065(t *testing.T) { test30065(t) }
|
func Test30065(t *testing.T) { test30065(t) }
|
||||||
func Test32579(t *testing.T) { test32579(t) }
|
func Test32579(t *testing.T) { test32579(t) }
|
||||||
|
func Test31891(t *testing.T) { test31891(t) }
|
||||||
func TestAlign(t *testing.T) { testAlign(t) }
|
func TestAlign(t *testing.T) { testAlign(t) }
|
||||||
func TestAtol(t *testing.T) { testAtol(t) }
|
func TestAtol(t *testing.T) { testAtol(t) }
|
||||||
func TestBlocking(t *testing.T) { testBlocking(t) }
|
func TestBlocking(t *testing.T) { testBlocking(t) }
|
||||||
|
|
@ -91,5 +92,6 @@ func TestThreadLock(t *testing.T) { testThreadLockFunc(t) }
|
||||||
func TestUnsignedInt(t *testing.T) { testUnsignedInt(t) }
|
func TestUnsignedInt(t *testing.T) { testUnsignedInt(t) }
|
||||||
func TestZeroArgCallback(t *testing.T) { testZeroArgCallback(t) }
|
func TestZeroArgCallback(t *testing.T) { testZeroArgCallback(t) }
|
||||||
|
|
||||||
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
|
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
|
||||||
func BenchmarkGoString(b *testing.B) { benchGoString(b) }
|
func BenchmarkGoString(b *testing.B) { benchGoString(b) }
|
||||||
|
func BenchmarkCGoCallback(b *testing.B) { benchCallback(b) }
|
||||||
|
|
|
||||||
13
misc/cgo/test/issue31891.c
Normal file
13
misc/cgo/test/issue31891.c
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
// 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 "_cgo_export.h"
|
||||||
|
|
||||||
|
void callIssue31891() {
|
||||||
|
Issue31891A a;
|
||||||
|
useIssue31891A(&a);
|
||||||
|
|
||||||
|
Issue31891B b;
|
||||||
|
useIssue31891B(&b);
|
||||||
|
}
|
||||||
|
|
@ -52,7 +52,7 @@ func overlayDir(dstRoot, srcRoot string) error {
|
||||||
// Always copy directories (don't symlink them).
|
// Always copy directories (don't symlink them).
|
||||||
// If we add a file in the overlay, we don't want to add it in the original.
|
// If we add a file in the overlay, we don't want to add it in the original.
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
return os.Mkdir(dstPath, perm)
|
return os.Mkdir(dstPath, perm|0200)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the OS supports symlinks, use them instead of copying bytes.
|
// If the OS supports symlinks, use them instead of copying bytes.
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,44 @@ int add(int x, int y) {
|
||||||
return x+y;
|
return x+y;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Following mimicks vulkan complex definitions for benchmarking cgocheck overhead.
|
||||||
|
|
||||||
|
typedef uint32_t VkFlags;
|
||||||
|
typedef VkFlags VkDeviceQueueCreateFlags;
|
||||||
|
typedef uint32_t VkStructureType;
|
||||||
|
|
||||||
|
typedef struct VkDeviceQueueCreateInfo {
|
||||||
|
VkStructureType sType;
|
||||||
|
const void* pNext;
|
||||||
|
VkDeviceQueueCreateFlags flags;
|
||||||
|
uint32_t queueFamilyIndex;
|
||||||
|
uint32_t queueCount;
|
||||||
|
const float* pQueuePriorities;
|
||||||
|
} VkDeviceQueueCreateInfo;
|
||||||
|
|
||||||
|
typedef struct VkPhysicalDeviceFeatures {
|
||||||
|
uint32_t bools[56];
|
||||||
|
} VkPhysicalDeviceFeatures;
|
||||||
|
|
||||||
|
typedef struct VkDeviceCreateInfo {
|
||||||
|
VkStructureType sType;
|
||||||
|
const void* pNext;
|
||||||
|
VkFlags flags;
|
||||||
|
uint32_t queueCreateInfoCount;
|
||||||
|
const VkDeviceQueueCreateInfo* pQueueCreateInfos;
|
||||||
|
uint32_t enabledLayerCount;
|
||||||
|
const char* const* ppEnabledLayerNames;
|
||||||
|
uint32_t enabledExtensionCount;
|
||||||
|
const char* const* ppEnabledExtensionNames;
|
||||||
|
const VkPhysicalDeviceFeatures* pEnabledFeatures;
|
||||||
|
} VkDeviceCreateInfo;
|
||||||
|
|
||||||
|
void handleComplexPointer(VkDeviceCreateInfo *a0) {}
|
||||||
|
void handleComplexPointer8(
|
||||||
|
VkDeviceCreateInfo *a0, VkDeviceCreateInfo *a1, VkDeviceCreateInfo *a2, VkDeviceCreateInfo *a3,
|
||||||
|
VkDeviceCreateInfo *a4, VkDeviceCreateInfo *a5, VkDeviceCreateInfo *a6, VkDeviceCreateInfo *a7
|
||||||
|
) {}
|
||||||
|
|
||||||
// complex alignment
|
// complex alignment
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -993,10 +1031,55 @@ type Context struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func benchCgoCall(b *testing.B) {
|
func benchCgoCall(b *testing.B) {
|
||||||
const x = C.int(2)
|
b.Run("add-int", func(b *testing.B) {
|
||||||
const y = C.int(3)
|
const x = C.int(2)
|
||||||
|
const y = C.int(3)
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
C.add(x, y)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
b.Run("one-pointer", func(b *testing.B) {
|
||||||
|
var a0 C.VkDeviceCreateInfo
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
C.handleComplexPointer(&a0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("eight-pointers", func(b *testing.B) {
|
||||||
|
var a0, a1, a2, a3, a4, a5, a6, a7 C.VkDeviceCreateInfo
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
C.handleComplexPointer8(&a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("eight-pointers-nil", func(b *testing.B) {
|
||||||
|
var a0, a1, a2, a3, a4, a5, a6, a7 *C.VkDeviceCreateInfo
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
C.handleComplexPointer8(a0, a1, a2, a3, a4, a5, a6, a7)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("eight-pointers-array", func(b *testing.B) {
|
||||||
|
var a [8]C.VkDeviceCreateInfo
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
C.handleComplexPointer8(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("eight-pointers-slice", func(b *testing.B) {
|
||||||
|
a := make([]C.VkDeviceCreateInfo, 8)
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
C.handleComplexPointer8(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Benchmark measuring overhead from Go to C and back to Go (via a callback)
|
||||||
|
func benchCallback(b *testing.B) {
|
||||||
|
var x = false
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
C.add(x, y)
|
nestedCall(func() { x = true })
|
||||||
|
}
|
||||||
|
if !x {
|
||||||
|
b.Fatal("nestedCall was not invoked")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1950,11 +2033,20 @@ func test27660(t *testing.T) {
|
||||||
// increase the likelihood that the race described in #27660
|
// increase the likelihood that the race described in #27660
|
||||||
// results in corruption of ThreadSanitizer's internal state
|
// results in corruption of ThreadSanitizer's internal state
|
||||||
// and thus an assertion failure or segfault.
|
// and thus an assertion failure or segfault.
|
||||||
|
i := 0
|
||||||
for ctx.Err() == nil {
|
for ctx.Err() == nil {
|
||||||
j := rand.Intn(100)
|
j := rand.Intn(100)
|
||||||
locks[j].Lock()
|
locks[j].Lock()
|
||||||
ints[j]++
|
ints[j]++
|
||||||
locks[j].Unlock()
|
locks[j].Unlock()
|
||||||
|
// needed for gccgo, to avoid creation of an
|
||||||
|
// unpreemptible "fast path" in this loop. Choice
|
||||||
|
// of (1<<24) is somewhat arbitrary.
|
||||||
|
if i%(1<<24) == 0 {
|
||||||
|
runtime.Gosched()
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
time.Sleep(time.Millisecond)
|
time.Sleep(time.Millisecond)
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ func Test(t *testing.T) {
|
||||||
// Brittle: the assertion may fail spuriously when the algorithm
|
// Brittle: the assertion may fail spuriously when the algorithm
|
||||||
// changes, but should remain stable otherwise.
|
// changes, but should remain stable otherwise.
|
||||||
got := fmt.Sprintf("%T %T", in, opts)
|
got := fmt.Sprintf("%T %T", in, opts)
|
||||||
want := "issue9026._Ctype_struct___0 *issue9026._Ctype_struct___0"
|
want := "issue9026._Ctype_struct___0 *issue9026._Ctype_struct___1"
|
||||||
if got != want {
|
if got != want {
|
||||||
t.Errorf("Non-deterministic type names: got %s, want %s", got, want)
|
t.Errorf("Non-deterministic type names: got %s, want %s", got, want)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,33 +83,18 @@ extern void f7665(void);
|
||||||
|
|
||||||
void issue7978cb(void);
|
void issue7978cb(void);
|
||||||
|
|
||||||
#if defined(__APPLE__) && defined(__arm__)
|
|
||||||
// on Darwin/ARM, libSystem doesn't provide implementation of the __sync_fetch_and_add
|
|
||||||
// primitive, and although gcc supports it, it doesn't inline its definition.
|
|
||||||
// Clang could inline its definition, so we require clang on Darwin/ARM.
|
|
||||||
#if defined(__clang__)
|
|
||||||
#define HAS_SYNC_FETCH_AND_ADD 1
|
|
||||||
#else
|
|
||||||
#define HAS_SYNC_FETCH_AND_ADD 0
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define HAS_SYNC_FETCH_AND_ADD 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// use ugly atomic variable sync since that doesn't require calling back into
|
// use ugly atomic variable sync since that doesn't require calling back into
|
||||||
// Go code or OS dependencies
|
// Go code or OS dependencies
|
||||||
static void issue7978c(uint32_t *sync) {
|
static void issue7978c(uint32_t *sync) {
|
||||||
#if HAS_SYNC_FETCH_AND_ADD
|
while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 0)
|
||||||
while(__sync_fetch_and_add(sync, 0) != 0)
|
|
||||||
;
|
;
|
||||||
__sync_fetch_and_add(sync, 1);
|
__atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST);
|
||||||
while(__sync_fetch_and_add(sync, 0) != 2)
|
while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 2)
|
||||||
;
|
;
|
||||||
issue7978cb();
|
issue7978cb();
|
||||||
__sync_fetch_and_add(sync, 1);
|
__atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST);
|
||||||
while(__sync_fetch_and_add(sync, 0) != 6)
|
while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 6)
|
||||||
;
|
;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// issue 8331 part 2 - part 1 in test.go
|
// issue 8331 part 2 - part 1 in test.go
|
||||||
|
|
@ -123,6 +108,17 @@ void callMulti(void);
|
||||||
// issue 28772 part 2 - part 1 in issuex.go
|
// issue 28772 part 2 - part 1 in issuex.go
|
||||||
#define issue28772Constant2 2
|
#define issue28772Constant2 2
|
||||||
|
|
||||||
|
|
||||||
|
// issue 31891
|
||||||
|
typedef struct {
|
||||||
|
long obj;
|
||||||
|
} Issue31891A;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
long obj;
|
||||||
|
} Issue31891B;
|
||||||
|
|
||||||
|
void callIssue31891(void);
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
|
|
@ -496,9 +492,6 @@ func test7978(t *testing.T) {
|
||||||
if runtime.Compiler == "gccgo" {
|
if runtime.Compiler == "gccgo" {
|
||||||
t.Skip("gccgo can not do stack traces of C code")
|
t.Skip("gccgo can not do stack traces of C code")
|
||||||
}
|
}
|
||||||
if C.HAS_SYNC_FETCH_AND_ADD == 0 {
|
|
||||||
t.Skip("clang required for __sync_fetch_and_add support on darwin/arm")
|
|
||||||
}
|
|
||||||
debug.SetTraceback("2")
|
debug.SetTraceback("2")
|
||||||
issue7978sync = 0
|
issue7978sync = 0
|
||||||
go issue7978go()
|
go issue7978go()
|
||||||
|
|
@ -535,3 +528,15 @@ func test20910(t *testing.T) {
|
||||||
// issue 28772 part 2
|
// issue 28772 part 2
|
||||||
|
|
||||||
const issue28772Constant2 = C.issue28772Constant2
|
const issue28772Constant2 = C.issue28772Constant2
|
||||||
|
|
||||||
|
// issue 31891
|
||||||
|
|
||||||
|
//export useIssue31891A
|
||||||
|
func useIssue31891A(c *C.Issue31891A) {}
|
||||||
|
|
||||||
|
//export useIssue31891B
|
||||||
|
func useIssue31891B(c *C.Issue31891B) {}
|
||||||
|
|
||||||
|
func test31891(t *testing.T) {
|
||||||
|
C.callIssue31891()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,13 @@ func TestEarlySignalHandler(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if out, err := exec.Command(bin[0], bin[1:]...).CombinedOutput(); err != nil {
|
darwin := "0"
|
||||||
|
if runtime.GOOS == "darwin" {
|
||||||
|
darwin = "1"
|
||||||
|
}
|
||||||
|
cmd = exec.Command(bin[0], append(bin[1:], darwin)...)
|
||||||
|
|
||||||
|
if out, err := cmd.CombinedOutput(); err != nil {
|
||||||
t.Logf("%s", out)
|
t.Logf("%s", out)
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -320,12 +326,15 @@ func TestSignalForwarding(t *testing.T) {
|
||||||
t.Logf("%s", out)
|
t.Logf("%s", out)
|
||||||
expectSignal(t, err, syscall.SIGSEGV)
|
expectSignal(t, err, syscall.SIGSEGV)
|
||||||
|
|
||||||
// Test SIGPIPE forwarding
|
// SIGPIPE is never forwarded on darwin. See golang.org/issue/33384.
|
||||||
cmd = exec.Command(bin[0], append(bin[1:], "3")...)
|
if runtime.GOOS != "darwin" {
|
||||||
|
// Test SIGPIPE forwarding
|
||||||
|
cmd = exec.Command(bin[0], append(bin[1:], "3")...)
|
||||||
|
|
||||||
out, err = cmd.CombinedOutput()
|
out, err = cmd.CombinedOutput()
|
||||||
t.Logf("%s", out)
|
t.Logf("%s", out)
|
||||||
expectSignal(t, err, syscall.SIGPIPE)
|
expectSignal(t, err, syscall.SIGPIPE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSignalForwardingExternal(t *testing.T) {
|
func TestSignalForwardingExternal(t *testing.T) {
|
||||||
|
|
@ -744,11 +753,20 @@ func TestCompileWithoutShared(t *testing.T) {
|
||||||
}
|
}
|
||||||
defer os.Remove(exe)
|
defer os.Remove(exe)
|
||||||
|
|
||||||
binArgs := append(cmdToRun(exe), "3")
|
binArgs := append(cmdToRun(exe), "1")
|
||||||
t.Log(binArgs)
|
t.Log(binArgs)
|
||||||
out, err = exec.Command(binArgs[0], binArgs[1:]...).CombinedOutput()
|
out, err = exec.Command(binArgs[0], binArgs[1:]...).CombinedOutput()
|
||||||
t.Logf("%s", out)
|
t.Logf("%s", out)
|
||||||
expectSignal(t, err, syscall.SIGPIPE)
|
expectSignal(t, err, syscall.SIGSEGV)
|
||||||
|
|
||||||
|
// SIGPIPE is never forwarded on darwin. See golang.org/issue/33384.
|
||||||
|
if runtime.GOOS != "darwin" {
|
||||||
|
binArgs := append(cmdToRun(exe), "3")
|
||||||
|
t.Log(binArgs)
|
||||||
|
out, err = exec.Command(binArgs[0], binArgs[1:]...).CombinedOutput()
|
||||||
|
t.Logf("%s", out)
|
||||||
|
expectSignal(t, err, syscall.SIGPIPE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that installing a second time recreates the header files.
|
// Test that installing a second time recreates the header files.
|
||||||
|
|
@ -795,3 +813,52 @@ func TestCachedInstall(t *testing.T) {
|
||||||
t.Errorf("p.h not installed in second run: %v", err)
|
t.Errorf("p.h not installed in second run: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue 35294.
|
||||||
|
func TestManyCalls(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
os.Remove("testp7" + exeSuffix)
|
||||||
|
os.Remove("libgo7.a")
|
||||||
|
os.Remove("libgo7.h")
|
||||||
|
}()
|
||||||
|
|
||||||
|
cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo7.a", "./libgo7")
|
||||||
|
if out, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
t.Logf("%s", out)
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
checkLineComments(t, "libgo7.h")
|
||||||
|
|
||||||
|
ccArgs := append(cc, "-o", "testp7"+exeSuffix, "main7.c", "libgo7.a")
|
||||||
|
if runtime.Compiler == "gccgo" {
|
||||||
|
ccArgs = append(ccArgs, "-lgo")
|
||||||
|
}
|
||||||
|
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
|
||||||
|
t.Logf("%s", out)
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
argv := cmdToRun("./testp7")
|
||||||
|
cmd = exec.Command(argv[0], argv[1:]...)
|
||||||
|
var sb strings.Builder
|
||||||
|
cmd.Stdout = &sb
|
||||||
|
cmd.Stderr = &sb
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
timer := time.AfterFunc(time.Minute,
|
||||||
|
func() {
|
||||||
|
t.Error("test program timed out")
|
||||||
|
cmd.Process.Kill()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
defer timer.Stop()
|
||||||
|
|
||||||
|
if err := cmd.Wait(); err != nil {
|
||||||
|
t.Log(sb.String())
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ func overlayDir(dstRoot, srcRoot string) error {
|
||||||
// Always copy directories (don't symlink them).
|
// Always copy directories (don't symlink them).
|
||||||
// If we add a file in the overlay, we don't want to add it in the original.
|
// If we add a file in the overlay, we don't want to add it in the original.
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
return os.Mkdir(dstPath, perm)
|
return os.Mkdir(dstPath, perm|0200)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the OS supports symlinks, use them instead of copying bytes.
|
// If the OS supports symlinks, use them instead of copying bytes.
|
||||||
|
|
|
||||||
17
misc/cgo/testcarchive/testdata/libgo7/sink.go
vendored
Normal file
17
misc/cgo/testcarchive/testdata/libgo7/sink.go
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
// 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 main
|
||||||
|
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
var sink []byte
|
||||||
|
|
||||||
|
//export GoFunction7
|
||||||
|
func GoFunction7() {
|
||||||
|
sink = make([]byte, 4096)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
}
|
||||||
37
misc/cgo/testcarchive/testdata/main2.c
vendored
37
misc/cgo/testcarchive/testdata/main2.c
vendored
|
|
@ -123,8 +123,12 @@ int main(int argc, char** argv) {
|
||||||
sigset_t mask;
|
sigset_t mask;
|
||||||
int i;
|
int i;
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
int darwin;
|
||||||
|
|
||||||
|
darwin = atoi(argv[1]);
|
||||||
|
|
||||||
|
verbose = argc > 2;
|
||||||
|
|
||||||
verbose = argc > 1;
|
|
||||||
setvbuf(stdout, NULL, _IONBF, 0);
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
|
|
||||||
// Call setsid so that we can use kill(0, SIGIO) below.
|
// Call setsid so that we can use kill(0, SIGIO) below.
|
||||||
|
|
@ -186,22 +190,25 @@ int main(int argc, char** argv) {
|
||||||
printf("provoking SIGPIPE\n");
|
printf("provoking SIGPIPE\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
GoRaiseSIGPIPE();
|
// SIGPIPE is never forwarded on Darwin, see golang.org/issue/33384.
|
||||||
|
if (!darwin) {
|
||||||
|
GoRaiseSIGPIPE();
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printf("waiting for sigpipeSeen\n");
|
printf("waiting for sigpipeSeen\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until the signal has been delivered.
|
// Wait until the signal has been delivered.
|
||||||
i = 0;
|
i = 0;
|
||||||
while (!sigpipeSeen) {
|
while (!sigpipeSeen) {
|
||||||
ts.tv_sec = 0;
|
ts.tv_sec = 0;
|
||||||
ts.tv_nsec = 1000000;
|
ts.tv_nsec = 1000000;
|
||||||
nanosleep(&ts, NULL);
|
nanosleep(&ts, NULL);
|
||||||
i++;
|
i++;
|
||||||
if (i > 5000) {
|
if (i > 5000) {
|
||||||
fprintf(stderr, "looping too long waiting for SIGPIPE\n");
|
fprintf(stderr, "looping too long waiting for SIGPIPE\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
21
misc/cgo/testcarchive/testdata/main3.c
vendored
21
misc/cgo/testcarchive/testdata/main3.c
vendored
|
|
@ -12,6 +12,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "libgo3.h"
|
#include "libgo3.h"
|
||||||
|
|
||||||
|
|
@ -51,11 +52,18 @@ static void init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *provokeSIGPIPE(void *arg) {
|
||||||
|
ProvokeSIGPIPE();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
int verbose;
|
int verbose;
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
int i;
|
int i;
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
int res;
|
||||||
|
pthread_t tid;
|
||||||
|
|
||||||
verbose = argc > 2;
|
verbose = argc > 2;
|
||||||
setvbuf(stdout, NULL, _IONBF, 0);
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
|
|
@ -68,6 +76,19 @@ int main(int argc, char** argv) {
|
||||||
// a non-default SIGPIPE handler before the runtime initializes.
|
// a non-default SIGPIPE handler before the runtime initializes.
|
||||||
ProvokeSIGPIPE();
|
ProvokeSIGPIPE();
|
||||||
|
|
||||||
|
// Test that SIGPIPE on a non-main thread is also handled by Go.
|
||||||
|
res = pthread_create(&tid, NULL, provokeSIGPIPE, NULL);
|
||||||
|
if (res != 0) {
|
||||||
|
fprintf(stderr, "pthread_create: %s\n", strerror(res));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = pthread_join(tid, NULL);
|
||||||
|
if (res != 0) {
|
||||||
|
fprintf(stderr, "pthread_join: %s\n", strerror(res));
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printf("calling sigaction\n");
|
printf("calling sigaction\n");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
18
misc/cgo/testcarchive/testdata/main7.c
vendored
Normal file
18
misc/cgo/testcarchive/testdata/main7.c
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// Test that lots of calls don't deadlock.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "libgo7.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 100000; i++) {
|
||||||
|
GoFunction7();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -52,7 +52,7 @@ func overlayDir(dstRoot, srcRoot string) error {
|
||||||
// Always copy directories (don't symlink them).
|
// Always copy directories (don't symlink them).
|
||||||
// If we add a file in the overlay, we don't want to add it in the original.
|
// If we add a file in the overlay, we don't want to add it in the original.
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
return os.Mkdir(dstPath, perm)
|
return os.Mkdir(dstPath, perm|0200)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the OS supports symlinks, use them instead of copying bytes.
|
// If the OS supports symlinks, use them instead of copying bytes.
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ func overlayDir(dstRoot, srcRoot string) error {
|
||||||
// Always copy directories (don't symlink them).
|
// Always copy directories (don't symlink them).
|
||||||
// If we add a file in the overlay, we don't want to add it in the original.
|
// If we add a file in the overlay, we don't want to add it in the original.
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
return os.Mkdir(dstPath, perm)
|
return os.Mkdir(dstPath, perm|0200)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the OS supports symlinks, use them instead of copying bytes.
|
// If the OS supports symlinks, use them instead of copying bytes.
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -114,11 +113,7 @@ func run(t *testing.T, bin string, args ...string) string {
|
||||||
|
|
||||||
func TestDWARFSections(t *testing.T) {
|
func TestDWARFSections(t *testing.T) {
|
||||||
// test that DWARF sections are emitted for plugins and programs importing "plugin"
|
// test that DWARF sections are emitted for plugins and programs importing "plugin"
|
||||||
if runtime.GOOS != "darwin" {
|
goCmd(t, "run", "./checkdwarf/main.go", "plugin2.so", "plugin2.UnexportedNameReuse")
|
||||||
// On macOS, for some reason, the linker doesn't add debug sections to .so,
|
|
||||||
// see issue #27502.
|
|
||||||
goCmd(t, "run", "./checkdwarf/main.go", "plugin2.so", "plugin2.UnexportedNameReuse")
|
|
||||||
}
|
|
||||||
goCmd(t, "run", "./checkdwarf/main.go", "./host.exe", "main.main")
|
goCmd(t, "run", "./checkdwarf/main.go", "./host.exe", "main.main")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ func overlayDir(dstRoot, srcRoot string) error {
|
||||||
// Always copy directories (don't symlink them).
|
// Always copy directories (don't symlink them).
|
||||||
// If we add a file in the overlay, we don't want to add it in the original.
|
// If we add a file in the overlay, we don't want to add it in the original.
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
return os.Mkdir(dstPath, perm)
|
return os.Mkdir(dstPath, perm|0200)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the OS supports symlinks, use them instead of copying bytes.
|
// If the OS supports symlinks, use them instead of copying bytes.
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ func overlayDir(dstRoot, srcRoot string) error {
|
||||||
// Always copy directories (don't symlink them).
|
// Always copy directories (don't symlink them).
|
||||||
// If we add a file in the overlay, we don't want to add it in the original.
|
// If we add a file in the overlay, we don't want to add it in the original.
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
return os.Mkdir(dstPath, perm)
|
return os.Mkdir(dstPath, perm|0200)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the OS supports symlinks, use them instead of copying bytes.
|
// If the OS supports symlinks, use them instead of copying bytes.
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ func overlayDir(dstRoot, srcRoot string) error {
|
||||||
// Always copy directories (don't symlink them).
|
// Always copy directories (don't symlink them).
|
||||||
// If we add a file in the overlay, we don't want to add it in the original.
|
// If we add a file in the overlay, we don't want to add it in the original.
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
return os.Mkdir(dstPath, perm)
|
return os.Mkdir(dstPath, perm|0200)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the OS supports symlinks, use them instead of copying bytes.
|
// If the OS supports symlinks, use them instead of copying bytes.
|
||||||
|
|
|
||||||
|
|
@ -17,4 +17,4 @@ else
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec $CLANG -arch $CLANGARCH -isysroot $SDK_PATH -mios-version-min=6.0 "$@"
|
exec $CLANG -arch $CLANGARCH -isysroot $SDK_PATH -mios-version-min=10.0 "$@"
|
||||||
|
|
|
||||||
121
misc/nacl/README
121
misc/nacl/README
|
|
@ -1,121 +0,0 @@
|
||||||
Native Client
|
|
||||||
=============
|
|
||||||
|
|
||||||
This document outlines the basics of building and developing the Go runtime and
|
|
||||||
programs in the Native Client (NaCl) environment.
|
|
||||||
|
|
||||||
Go 1.3 supports three architectures
|
|
||||||
|
|
||||||
* nacl/386 which is standard 386.
|
|
||||||
* nacl/amd64p32 which is a 64 bit architecture, where the address space is
|
|
||||||
limited to a 4gb window.
|
|
||||||
* nacl/arm which is 32-bit ARMv7A architecture with 1GB address space.
|
|
||||||
|
|
||||||
For background it is recommended that you read https://golang.org/s/go13nacl.
|
|
||||||
|
|
||||||
Prerequisites
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Native Client programs are executed inside a sandbox, the NaCl runtime. This
|
|
||||||
runtime must be installed before you can use NaCl programs.
|
|
||||||
|
|
||||||
The NaCl distribution comes with an installer which ensures you have access to
|
|
||||||
the latest version of the runtime. The version tracks the Chrome numbering
|
|
||||||
scheme.
|
|
||||||
|
|
||||||
# Download NaCl
|
|
||||||
|
|
||||||
Download nacl_sdk.zip file from
|
|
||||||
https://developer.chrome.com/native-client/sdk/download
|
|
||||||
and unpack it. I chose /opt/nacl_sdk.
|
|
||||||
|
|
||||||
# Update
|
|
||||||
|
|
||||||
The zip file contains a small skeleton that can be used to download the correct
|
|
||||||
sdk. These are released every 6-8 weeks, in line with Chrome releases.
|
|
||||||
|
|
||||||
% cd /opt/nacl_sdk
|
|
||||||
% ./naclsdk update
|
|
||||||
|
|
||||||
At this time pepper_49 is the stable version. The NaCl port needs at least pepper_39
|
|
||||||
to work. If naclsdk downloads a later version, please adjust accordingly.
|
|
||||||
|
|
||||||
The cmd/go helper scripts expect that the loaders sel_ldr_{x86_{32,64},arm} and
|
|
||||||
nacl_helper_bootstrap_arm are in your path. I find it easiest to make a symlink
|
|
||||||
from the NaCl distribution to my $GOPATH/bin directory.
|
|
||||||
|
|
||||||
% ln -nfs /opt/nacl_sdk/pepper_39/tools/sel_ldr_x86_32 $GOPATH/bin/sel_ldr_x86_32
|
|
||||||
% ln -nfs /opt/nacl_sdk/pepper_39/tools/sel_ldr_x86_64 $GOPATH/bin/sel_ldr_x86_64
|
|
||||||
% ln -nfs /opt/nacl_sdk/pepper_39/tools/sel_ldr_arm $GOPATH/bin/sel_ldr_arm
|
|
||||||
|
|
||||||
Additionally, for NaCl/ARM only:
|
|
||||||
|
|
||||||
% ln -nfs /opt/nacl_sdk/pepper_39/tools/nacl_helper_bootstrap_arm $GOPATH/bin/nacl_helper_bootstrap_arm
|
|
||||||
|
|
||||||
Support scripts
|
|
||||||
---------------
|
|
||||||
|
|
||||||
Symlink the two scripts in this directory into your $PATH, just as you did with
|
|
||||||
NaCl sdk above.
|
|
||||||
|
|
||||||
% ln -nfs $GOROOT/misc/nacl/go_nacl_amd64p32_exec $GOPATH/bin/go_nacl_amd64p32_exec
|
|
||||||
% ln -nfs $GOROOT/misc/nacl/go_nacl_386_exec $GOPATH/bin/go_nacl_386_exec
|
|
||||||
% ln -nfs $GOROOT/misc/nacl/go_nacl_arm_exec $GOPATH/bin/go_nacl_arm_exec
|
|
||||||
|
|
||||||
Building and testing
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
Building for NaCl is similar to cross compiling for other platforms. However,
|
|
||||||
as it is not possible to ever build in a `native` NaCl environment, the cmd/go
|
|
||||||
tool has been enhanced to allow the full build, all.bash, to be executed,
|
|
||||||
rather than just the compile stage, make.bash.
|
|
||||||
|
|
||||||
The cmd/go tool knows that if GOOS is set to `nacl` it should not try to
|
|
||||||
execute any binaries itself. Instead it passes their execution to a support
|
|
||||||
script which sets up a Native Client environment and invokes the NaCl sandbox.
|
|
||||||
|
|
||||||
The script's name has a special format, go_$GOOS_$GOARCH_exec, so cmd/go can
|
|
||||||
find it.
|
|
||||||
|
|
||||||
In short, if the support scripts are in place, the cmd/go tool can be used as
|
|
||||||
per normal.
|
|
||||||
|
|
||||||
# Build and test Go for NaCl
|
|
||||||
|
|
||||||
NaCl does not permit direct file system access. Instead, package syscall
|
|
||||||
provides a simulated file system served by in-memory data. The script
|
|
||||||
nacltest.bash is the NaCl equivalent of all.bash. It builds NaCl with an
|
|
||||||
in-memory file system containing files needed for tests, and then it runs the
|
|
||||||
tests.
|
|
||||||
|
|
||||||
% cd go/src
|
|
||||||
% env GOARCH=amd64p32 ./nacltest.bash
|
|
||||||
|
|
||||||
Debugging
|
|
||||||
---------
|
|
||||||
|
|
||||||
Assuming that you have built nacl/amd64p32 binary ./mybin and can run as:
|
|
||||||
|
|
||||||
% sel_ldr_x86_64 -l /dev/null -S -e ./mybin
|
|
||||||
|
|
||||||
Create the nacl manifest file mybin.manifest with the following contents:
|
|
||||||
|
|
||||||
{ "program": { "x86-64": { "url": "mybin" } } }
|
|
||||||
|
|
||||||
url is the path to the binary relative to the manifest file.
|
|
||||||
Then, run the program as:
|
|
||||||
|
|
||||||
% sel_ldr_x86_64 -g -l /dev/null -S -e ./mybin
|
|
||||||
|
|
||||||
The -g flag instructs the loader to stop at startup. Then, in another console:
|
|
||||||
|
|
||||||
% /opt/nacl_sdk/pepper_39/toolchain/linux_x86_glibc/bin/x86_64-nacl-gdb
|
|
||||||
% nacl-manifest mybin.manifest
|
|
||||||
% target remote :4014
|
|
||||||
|
|
||||||
If you see that the program is stopped in _rt0_amd64p32_nacl, then symbols are
|
|
||||||
loaded successfully and you can type 'c' to start the program.
|
|
||||||
Next time you can automate it as:
|
|
||||||
|
|
||||||
% /opt/nacl_sdk/pepper_39/toolchain/linux_x86_glibc/bin/x86_64-nacl-gdb \
|
|
||||||
-ex 'nacl-manifest mybin.manifest' -ex 'target remote :4014'
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
eval $(go env)
|
|
||||||
|
|
||||||
export NACLENV_GOARCH=$GOARCH
|
|
||||||
export NACLENV_GOOS=$GOOS
|
|
||||||
export NACLENV_GOROOT=/go
|
|
||||||
export NACLENV_NACLPWD=$(pwd | sed "s;$GOROOT;/go;")
|
|
||||||
|
|
||||||
exec sel_ldr_x86_32 -l /dev/null -S -e "$@"
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
eval $(go env)
|
|
||||||
|
|
||||||
export NACLENV_GOARCH=$GOARCH
|
|
||||||
export NACLENV_GOOS=$GOOS
|
|
||||||
export NACLENV_GOROOT=/go
|
|
||||||
export NACLENV_NACLPWD=$(pwd | sed "s;$GOROOT;/go;")
|
|
||||||
|
|
||||||
exec sel_ldr_x86_64 -l /dev/null -S -e "$@"
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
eval $(go env)
|
|
||||||
|
|
||||||
export NACLENV_GOARCH=$GOARCH
|
|
||||||
export NACLENV_GOOS=$GOOS
|
|
||||||
export NACLENV_GOROOT=/go
|
|
||||||
export NACLENV_NACLPWD=$(pwd | sed "s;$GOROOT;/go;")
|
|
||||||
|
|
||||||
exec nacl_helper_bootstrap_arm $(which sel_ldr_arm) --reserved_at_zero=0xXXXXXXXXXXXXXXXX -l /dev/null -S -e "$@"
|
|
||||||
|
|
@ -1,226 +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.
|
|
||||||
|
|
||||||
// Mkzip creates a zip file from a 'proto' file describing the contents.
|
|
||||||
//
|
|
||||||
// The proto file is inspired by the Plan 9 mkfs prototype file format.
|
|
||||||
// It describes a file tree, one directory per line, with leading tab
|
|
||||||
// indentation marking the tree structure. Each line contains a leading
|
|
||||||
// name field giving the name of the file to copy into the zip file,
|
|
||||||
// and then a sequence of optional key=value attributes to control
|
|
||||||
// the copy. The only known attribute is src=foo, meaning copy the
|
|
||||||
// actual data for the file (or directory) from an alternate location.
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"archive/zip"
|
|
||||||
"bufio"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func usage() {
|
|
||||||
fmt.Fprintf(os.Stderr, "usage: mkzip [-r root] src.proto out.zip\n")
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
func sysfatal(format string, args ...interface{}) {
|
|
||||||
fmt.Fprintf(os.Stderr, "mkzip: %s\n", fmt.Sprintf(format, args...))
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
root = flag.String("r", ".", "interpret source paths relative to this directory")
|
|
||||||
gopackage = flag.String("p", "", "write Go source file in this package")
|
|
||||||
)
|
|
||||||
|
|
||||||
type stack struct {
|
|
||||||
name string
|
|
||||||
src string
|
|
||||||
depth int
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
log.SetFlags(0)
|
|
||||||
flag.Usage = usage
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
args := flag.Args()
|
|
||||||
if len(args) != 2 {
|
|
||||||
usage()
|
|
||||||
}
|
|
||||||
|
|
||||||
rf, err := os.Open(args[0])
|
|
||||||
if err != nil {
|
|
||||||
sysfatal("%v", err)
|
|
||||||
}
|
|
||||||
r := bufio.NewScanner(rf)
|
|
||||||
|
|
||||||
zf, err := os.Create(args[1])
|
|
||||||
if err != nil {
|
|
||||||
sysfatal("%v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var w io.Writer = zf
|
|
||||||
if *gopackage != "" {
|
|
||||||
fmt.Fprintf(zf, `package %s
|
|
||||||
import "sync"
|
|
||||||
func init() {
|
|
||||||
var once sync.Once
|
|
||||||
fsinit = func() {
|
|
||||||
once.Do(func() {
|
|
||||||
unzip("`, *gopackage)
|
|
||||||
gw := &goWriter{b: bufio.NewWriter(w)}
|
|
||||||
defer func() {
|
|
||||||
if err := gw.Close(); err != nil {
|
|
||||||
sysfatal("finishing Go output: %v", err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
w = gw
|
|
||||||
}
|
|
||||||
z := zip.NewWriter(w)
|
|
||||||
|
|
||||||
lineno := 0
|
|
||||||
|
|
||||||
addfile := func(info os.FileInfo, dst string, src string) {
|
|
||||||
zh, err := zip.FileInfoHeader(info)
|
|
||||||
if err != nil {
|
|
||||||
sysfatal("%s:%d: %s: %v", args[0], lineno, src, err)
|
|
||||||
}
|
|
||||||
zh.Name = dst
|
|
||||||
zh.Method = zip.Deflate
|
|
||||||
if info.IsDir() && !strings.HasSuffix(dst, "/") {
|
|
||||||
zh.Name += "/"
|
|
||||||
}
|
|
||||||
w, err := z.CreateHeader(zh)
|
|
||||||
if err != nil {
|
|
||||||
sysfatal("%s:%d: %s: %v", args[0], lineno, src, err)
|
|
||||||
}
|
|
||||||
if info.IsDir() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
r, err := os.Open(src)
|
|
||||||
if err != nil {
|
|
||||||
sysfatal("%s:%d: %s: %v", args[0], lineno, src, err)
|
|
||||||
}
|
|
||||||
defer r.Close()
|
|
||||||
if _, err := io.Copy(w, r); err != nil {
|
|
||||||
sysfatal("%s:%d: %s: %v", args[0], lineno, src, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var stk []stack
|
|
||||||
|
|
||||||
for r.Scan() {
|
|
||||||
line := r.Text()
|
|
||||||
lineno++
|
|
||||||
s := strings.TrimLeft(line, "\t")
|
|
||||||
prefix, line := line[:len(line)-len(s)], s
|
|
||||||
if i := strings.Index(line, "#"); i >= 0 {
|
|
||||||
line = line[:i]
|
|
||||||
}
|
|
||||||
f := strings.Fields(line)
|
|
||||||
if len(f) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(line, " ") {
|
|
||||||
sysfatal("%s:%d: must use tabs for indentation", args[0], lineno)
|
|
||||||
}
|
|
||||||
depth := len(prefix)
|
|
||||||
for len(stk) > 0 && depth <= stk[len(stk)-1].depth {
|
|
||||||
stk = stk[:len(stk)-1]
|
|
||||||
}
|
|
||||||
parent := ""
|
|
||||||
psrc := *root
|
|
||||||
if len(stk) > 0 {
|
|
||||||
parent = stk[len(stk)-1].name
|
|
||||||
psrc = stk[len(stk)-1].src
|
|
||||||
}
|
|
||||||
if strings.Contains(f[0], "/") {
|
|
||||||
sysfatal("%s:%d: destination name cannot contain slash", args[0], lineno)
|
|
||||||
}
|
|
||||||
name := path.Join(parent, f[0])
|
|
||||||
src := filepath.Join(psrc, f[0])
|
|
||||||
for _, attr := range f[1:] {
|
|
||||||
i := strings.Index(attr, "=")
|
|
||||||
if i < 0 {
|
|
||||||
sysfatal("%s:%d: malformed attribute %q", args[0], lineno, attr)
|
|
||||||
}
|
|
||||||
key, val := attr[:i], attr[i+1:]
|
|
||||||
switch key {
|
|
||||||
case "src":
|
|
||||||
src = val
|
|
||||||
default:
|
|
||||||
sysfatal("%s:%d: unknown attribute %q", args[0], lineno, attr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stk = append(stk, stack{name: name, src: src, depth: depth})
|
|
||||||
|
|
||||||
if f[0] == "*" || f[0] == "+" {
|
|
||||||
if f[0] == "*" {
|
|
||||||
dir, err := ioutil.ReadDir(psrc)
|
|
||||||
if err != nil {
|
|
||||||
sysfatal("%s:%d: %v", args[0], lineno, err)
|
|
||||||
}
|
|
||||||
for _, d := range dir {
|
|
||||||
addfile(d, path.Join(parent, d.Name()), filepath.Join(psrc, d.Name()))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err := filepath.Walk(psrc, func(src string, info os.FileInfo, err error) error {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if src == psrc {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if psrc == "." {
|
|
||||||
psrc = ""
|
|
||||||
}
|
|
||||||
name := path.Join(parent, filepath.ToSlash(src[len(psrc):]))
|
|
||||||
addfile(info, name, src)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
sysfatal("%s:%d: %v", args[0], lineno, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
fi, err := os.Stat(src)
|
|
||||||
if err != nil {
|
|
||||||
sysfatal("%s:%d: %v", args[0], lineno, err)
|
|
||||||
}
|
|
||||||
addfile(fi, name, src)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := z.Close(); err != nil {
|
|
||||||
sysfatal("finishing zip file: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type goWriter struct {
|
|
||||||
b *bufio.Writer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *goWriter) Write(b []byte) (int, error) {
|
|
||||||
for _, c := range b {
|
|
||||||
fmt.Fprintf(w.b, "\\x%02x", c)
|
|
||||||
}
|
|
||||||
return len(b), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *goWriter) Close() error {
|
|
||||||
fmt.Fprintf(w.b, "\")\n\t\t})\n\t}\n}")
|
|
||||||
w.b.Flush()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
0
misc/nacl/testdata/empty
vendored
0
misc/nacl/testdata/empty
vendored
8
misc/nacl/testdata/group
vendored
8
misc/nacl/testdata/group
vendored
|
|
@ -1,8 +0,0 @@
|
||||||
nobody:*:-2:
|
|
||||||
nogroup:*:-1:
|
|
||||||
wheel:*:0:root
|
|
||||||
daemon:*:1:root
|
|
||||||
kmem:*:2:root
|
|
||||||
sys:*:3:root
|
|
||||||
tty:*:4:root
|
|
||||||
operator:*:5:root
|
|
||||||
1
misc/nacl/testdata/hosts
vendored
1
misc/nacl/testdata/hosts
vendored
|
|
@ -1 +0,0 @@
|
||||||
127.0.0.1 localhost
|
|
||||||
1596
misc/nacl/testdata/mime.types
vendored
1596
misc/nacl/testdata/mime.types
vendored
File diff suppressed because it is too large
Load diff
|
|
@ -1,190 +0,0 @@
|
||||||
etc src=/etc
|
|
||||||
mime.types src=../misc/nacl/testdata/mime.types
|
|
||||||
resolv.conf src=../misc/nacl/testdata/empty
|
|
||||||
group src=../misc/nacl/testdata/group
|
|
||||||
passwd src=../misc/nacl/testdata/empty
|
|
||||||
hosts src=../misc/nacl/testdata/hosts
|
|
||||||
services
|
|
||||||
usr src=../misc/nacl/testdata
|
|
||||||
bin
|
|
||||||
go src=..
|
|
||||||
src
|
|
||||||
cmd
|
|
||||||
api
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
asm
|
|
||||||
internal
|
|
||||||
asm
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
compile
|
|
||||||
internal
|
|
||||||
syntax
|
|
||||||
parser.go
|
|
||||||
cover
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
doc
|
|
||||||
main.go
|
|
||||||
pkg.go
|
|
||||||
doc_test.go
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
internal
|
|
||||||
objfile
|
|
||||||
objfile.go
|
|
||||||
buildid
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
gofmt
|
|
||||||
gofmt.go
|
|
||||||
gofmt_test.go
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
vendor
|
|
||||||
github.com
|
|
||||||
google
|
|
||||||
pprof
|
|
||||||
internal
|
|
||||||
binutils
|
|
||||||
+
|
|
||||||
driver
|
|
||||||
+
|
|
||||||
graph
|
|
||||||
+
|
|
||||||
report
|
|
||||||
+
|
|
||||||
profile
|
|
||||||
+
|
|
||||||
ianlancetaylor
|
|
||||||
demangle
|
|
||||||
+
|
|
||||||
golang.org
|
|
||||||
x
|
|
||||||
arch
|
|
||||||
arm
|
|
||||||
armasm
|
|
||||||
+
|
|
||||||
arm64
|
|
||||||
arm64asm
|
|
||||||
+
|
|
||||||
x86
|
|
||||||
x86asm
|
|
||||||
+
|
|
||||||
ppc64
|
|
||||||
ppc64asm
|
|
||||||
+
|
|
||||||
archive
|
|
||||||
tar
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
zip
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
compress
|
|
||||||
bzip2
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
flate
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
gzip
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
lzw
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
zlib
|
|
||||||
crypto
|
|
||||||
ed25519
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
rsa
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
tls
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
debug
|
|
||||||
dwarf
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
elf
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
macho
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
pe
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
plan9obj
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
go
|
|
||||||
build
|
|
||||||
+
|
|
||||||
doc
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
format
|
|
||||||
+
|
|
||||||
parser
|
|
||||||
+
|
|
||||||
printer
|
|
||||||
+
|
|
||||||
image
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
draw
|
|
||||||
gif
|
|
||||||
jpeg
|
|
||||||
png
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
internal
|
|
||||||
trace
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
xcoff
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
io
|
|
||||||
+
|
|
||||||
mime
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
multipart
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
net
|
|
||||||
http
|
|
||||||
+
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
os
|
|
||||||
+
|
|
||||||
path
|
|
||||||
filepath
|
|
||||||
+
|
|
||||||
regexp
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
runtime
|
|
||||||
textflag.h
|
|
||||||
strconv
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
text
|
|
||||||
template
|
|
||||||
testdata
|
|
||||||
+
|
|
||||||
lib
|
|
||||||
time
|
|
||||||
zoneinfo.zip
|
|
||||||
|
|
||||||
test
|
|
||||||
+
|
|
||||||
|
|
@ -51,7 +51,7 @@ func overlayDir(dstRoot, srcRoot string) error {
|
||||||
// Always copy directories (don't symlink them).
|
// Always copy directories (don't symlink them).
|
||||||
// If we add a file in the overlay, we don't want to add it in the original.
|
// If we add a file in the overlay, we don't want to add it in the original.
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
return os.Mkdir(dstPath, perm)
|
return os.Mkdir(dstPath, perm|0200)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the OS supports symlinks, use them instead of copying bytes.
|
// If the OS supports symlinks, use them instead of copying bytes.
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,12 @@
|
||||||
global.fs = require("fs");
|
global.fs = require("fs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const enosys = () => {
|
||||||
|
const err = new Error("not implemented");
|
||||||
|
err.code = "ENOSYS";
|
||||||
|
return err;
|
||||||
|
};
|
||||||
|
|
||||||
if (!global.fs) {
|
if (!global.fs) {
|
||||||
let outputBuf = "";
|
let outputBuf = "";
|
||||||
global.fs = {
|
global.fs = {
|
||||||
|
|
@ -45,27 +51,53 @@
|
||||||
},
|
},
|
||||||
write(fd, buf, offset, length, position, callback) {
|
write(fd, buf, offset, length, position, callback) {
|
||||||
if (offset !== 0 || length !== buf.length || position !== null) {
|
if (offset !== 0 || length !== buf.length || position !== null) {
|
||||||
throw new Error("not implemented");
|
callback(enosys());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
const n = this.writeSync(fd, buf);
|
const n = this.writeSync(fd, buf);
|
||||||
callback(null, n);
|
callback(null, n);
|
||||||
},
|
},
|
||||||
open(path, flags, mode, callback) {
|
chmod(path, mode, callback) { callback(enosys()); },
|
||||||
const err = new Error("not implemented");
|
chown(path, uid, gid, callback) { callback(enosys()); },
|
||||||
err.code = "ENOSYS";
|
close(fd, callback) { callback(enosys()); },
|
||||||
callback(err);
|
fchmod(fd, mode, callback) { callback(enosys()); },
|
||||||
},
|
fchown(fd, uid, gid, callback) { callback(enosys()); },
|
||||||
read(fd, buffer, offset, length, position, callback) {
|
fstat(fd, callback) { callback(enosys()); },
|
||||||
const err = new Error("not implemented");
|
fsync(fd, callback) { callback(null); },
|
||||||
err.code = "ENOSYS";
|
ftruncate(fd, length, callback) { callback(enosys()); },
|
||||||
callback(err);
|
lchown(path, uid, gid, callback) { callback(enosys()); },
|
||||||
},
|
link(path, link, callback) { callback(enosys()); },
|
||||||
fsync(fd, callback) {
|
lstat(path, callback) { callback(enosys()); },
|
||||||
callback(null);
|
mkdir(path, perm, callback) { callback(enosys()); },
|
||||||
},
|
open(path, flags, mode, callback) { callback(enosys()); },
|
||||||
|
read(fd, buffer, offset, length, position, callback) { callback(enosys()); },
|
||||||
|
readdir(path, callback) { callback(enosys()); },
|
||||||
|
readlink(path, callback) { callback(enosys()); },
|
||||||
|
rename(from, to, callback) { callback(enosys()); },
|
||||||
|
rmdir(path, callback) { callback(enosys()); },
|
||||||
|
stat(path, callback) { callback(enosys()); },
|
||||||
|
symlink(path, link, callback) { callback(enosys()); },
|
||||||
|
truncate(path, length, callback) { callback(enosys()); },
|
||||||
|
unlink(path, callback) { callback(enosys()); },
|
||||||
|
utimes(path, atime, mtime, callback) { callback(enosys()); },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!global.process) {
|
||||||
|
global.process = {
|
||||||
|
getuid() { return -1; },
|
||||||
|
getgid() { return -1; },
|
||||||
|
geteuid() { return -1; },
|
||||||
|
getegid() { return -1; },
|
||||||
|
getgroups() { throw enosys(); },
|
||||||
|
pid: -1,
|
||||||
|
ppid: -1,
|
||||||
|
umask() { throw enosys(); },
|
||||||
|
cwd() { throw enosys(); },
|
||||||
|
chdir() { throw enosys(); },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!global.crypto) {
|
if (!global.crypto) {
|
||||||
const nodeCrypto = require("crypto");
|
const nodeCrypto = require("crypto");
|
||||||
global.crypto = {
|
global.crypto = {
|
||||||
|
|
@ -113,24 +145,19 @@
|
||||||
this._scheduledTimeouts = new Map();
|
this._scheduledTimeouts = new Map();
|
||||||
this._nextCallbackTimeoutID = 1;
|
this._nextCallbackTimeoutID = 1;
|
||||||
|
|
||||||
const mem = () => {
|
|
||||||
// The buffer may change when requesting more memory.
|
|
||||||
return new DataView(this._inst.exports.mem.buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
const setInt64 = (addr, v) => {
|
const setInt64 = (addr, v) => {
|
||||||
mem().setUint32(addr + 0, v, true);
|
this.mem.setUint32(addr + 0, v, true);
|
||||||
mem().setUint32(addr + 4, Math.floor(v / 4294967296), true);
|
this.mem.setUint32(addr + 4, Math.floor(v / 4294967296), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getInt64 = (addr) => {
|
const getInt64 = (addr) => {
|
||||||
const low = mem().getUint32(addr + 0, true);
|
const low = this.mem.getUint32(addr + 0, true);
|
||||||
const high = mem().getInt32(addr + 4, true);
|
const high = this.mem.getInt32(addr + 4, true);
|
||||||
return low + high * 4294967296;
|
return low + high * 4294967296;
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadValue = (addr) => {
|
const loadValue = (addr) => {
|
||||||
const f = mem().getFloat64(addr, true);
|
const f = this.mem.getFloat64(addr, true);
|
||||||
if (f === 0) {
|
if (f === 0) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
@ -138,7 +165,7 @@
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = mem().getUint32(addr, true);
|
const id = this.mem.getUint32(addr, true);
|
||||||
return this._values[id];
|
return this._values[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -147,57 +174,62 @@
|
||||||
|
|
||||||
if (typeof v === "number") {
|
if (typeof v === "number") {
|
||||||
if (isNaN(v)) {
|
if (isNaN(v)) {
|
||||||
mem().setUint32(addr + 4, nanHead, true);
|
this.mem.setUint32(addr + 4, nanHead, true);
|
||||||
mem().setUint32(addr, 0, true);
|
this.mem.setUint32(addr, 0, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (v === 0) {
|
if (v === 0) {
|
||||||
mem().setUint32(addr + 4, nanHead, true);
|
this.mem.setUint32(addr + 4, nanHead, true);
|
||||||
mem().setUint32(addr, 1, true);
|
this.mem.setUint32(addr, 1, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mem().setFloat64(addr, v, true);
|
this.mem.setFloat64(addr, v, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (v) {
|
switch (v) {
|
||||||
case undefined:
|
case undefined:
|
||||||
mem().setFloat64(addr, 0, true);
|
this.mem.setFloat64(addr, 0, true);
|
||||||
return;
|
return;
|
||||||
case null:
|
case null:
|
||||||
mem().setUint32(addr + 4, nanHead, true);
|
this.mem.setUint32(addr + 4, nanHead, true);
|
||||||
mem().setUint32(addr, 2, true);
|
this.mem.setUint32(addr, 2, true);
|
||||||
return;
|
return;
|
||||||
case true:
|
case true:
|
||||||
mem().setUint32(addr + 4, nanHead, true);
|
this.mem.setUint32(addr + 4, nanHead, true);
|
||||||
mem().setUint32(addr, 3, true);
|
this.mem.setUint32(addr, 3, true);
|
||||||
return;
|
return;
|
||||||
case false:
|
case false:
|
||||||
mem().setUint32(addr + 4, nanHead, true);
|
this.mem.setUint32(addr + 4, nanHead, true);
|
||||||
mem().setUint32(addr, 4, true);
|
this.mem.setUint32(addr, 4, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ref = this._refs.get(v);
|
let id = this._ids.get(v);
|
||||||
if (ref === undefined) {
|
if (id === undefined) {
|
||||||
ref = this._values.length;
|
id = this._idPool.pop();
|
||||||
this._values.push(v);
|
if (id === undefined) {
|
||||||
this._refs.set(v, ref);
|
id = this._values.length;
|
||||||
|
}
|
||||||
|
this._values[id] = v;
|
||||||
|
this._goRefCounts[id] = 0;
|
||||||
|
this._ids.set(v, id);
|
||||||
}
|
}
|
||||||
let typeFlag = 0;
|
this._goRefCounts[id]++;
|
||||||
|
let typeFlag = 1;
|
||||||
switch (typeof v) {
|
switch (typeof v) {
|
||||||
case "string":
|
case "string":
|
||||||
typeFlag = 1;
|
|
||||||
break;
|
|
||||||
case "symbol":
|
|
||||||
typeFlag = 2;
|
typeFlag = 2;
|
||||||
break;
|
break;
|
||||||
case "function":
|
case "symbol":
|
||||||
typeFlag = 3;
|
typeFlag = 3;
|
||||||
break;
|
break;
|
||||||
|
case "function":
|
||||||
|
typeFlag = 4;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
mem().setUint32(addr + 4, nanHead | typeFlag, true);
|
this.mem.setUint32(addr + 4, nanHead | typeFlag, true);
|
||||||
mem().setUint32(addr, ref, true);
|
this.mem.setUint32(addr, id, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadSlice = (addr) => {
|
const loadSlice = (addr) => {
|
||||||
|
|
@ -232,11 +264,13 @@
|
||||||
|
|
||||||
// func wasmExit(code int32)
|
// func wasmExit(code int32)
|
||||||
"runtime.wasmExit": (sp) => {
|
"runtime.wasmExit": (sp) => {
|
||||||
const code = mem().getInt32(sp + 8, true);
|
const code = this.mem.getInt32(sp + 8, true);
|
||||||
this.exited = true;
|
this.exited = true;
|
||||||
delete this._inst;
|
delete this._inst;
|
||||||
delete this._values;
|
delete this._values;
|
||||||
delete this._refs;
|
delete this._goRefCounts;
|
||||||
|
delete this._ids;
|
||||||
|
delete this._idPool;
|
||||||
this.exit(code);
|
this.exit(code);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -244,20 +278,25 @@
|
||||||
"runtime.wasmWrite": (sp) => {
|
"runtime.wasmWrite": (sp) => {
|
||||||
const fd = getInt64(sp + 8);
|
const fd = getInt64(sp + 8);
|
||||||
const p = getInt64(sp + 16);
|
const p = getInt64(sp + 16);
|
||||||
const n = mem().getInt32(sp + 24, true);
|
const n = this.mem.getInt32(sp + 24, true);
|
||||||
fs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n));
|
fs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n));
|
||||||
},
|
},
|
||||||
|
|
||||||
// func nanotime() int64
|
// func resetMemoryDataView()
|
||||||
"runtime.nanotime": (sp) => {
|
"runtime.resetMemoryDataView": (sp) => {
|
||||||
|
this.mem = new DataView(this._inst.exports.mem.buffer);
|
||||||
|
},
|
||||||
|
|
||||||
|
// func nanotime1() int64
|
||||||
|
"runtime.nanotime1": (sp) => {
|
||||||
setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000);
|
setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000);
|
||||||
},
|
},
|
||||||
|
|
||||||
// func walltime() (sec int64, nsec int32)
|
// func walltime1() (sec int64, nsec int32)
|
||||||
"runtime.walltime": (sp) => {
|
"runtime.walltime1": (sp) => {
|
||||||
const msec = (new Date).getTime();
|
const msec = (new Date).getTime();
|
||||||
setInt64(sp + 8, msec / 1000);
|
setInt64(sp + 8, msec / 1000);
|
||||||
mem().setInt32(sp + 16, (msec % 1000) * 1000000, true);
|
this.mem.setInt32(sp + 16, (msec % 1000) * 1000000, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
// func scheduleTimeoutEvent(delay int64) int32
|
// func scheduleTimeoutEvent(delay int64) int32
|
||||||
|
|
@ -276,12 +315,12 @@
|
||||||
},
|
},
|
||||||
getInt64(sp + 8) + 1, // setTimeout has been seen to fire up to 1 millisecond early
|
getInt64(sp + 8) + 1, // setTimeout has been seen to fire up to 1 millisecond early
|
||||||
));
|
));
|
||||||
mem().setInt32(sp + 16, id, true);
|
this.mem.setInt32(sp + 16, id, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
// func clearTimeoutEvent(id int32)
|
// func clearTimeoutEvent(id int32)
|
||||||
"runtime.clearTimeoutEvent": (sp) => {
|
"runtime.clearTimeoutEvent": (sp) => {
|
||||||
const id = mem().getInt32(sp + 8, true);
|
const id = this.mem.getInt32(sp + 8, true);
|
||||||
clearTimeout(this._scheduledTimeouts.get(id));
|
clearTimeout(this._scheduledTimeouts.get(id));
|
||||||
this._scheduledTimeouts.delete(id);
|
this._scheduledTimeouts.delete(id);
|
||||||
},
|
},
|
||||||
|
|
@ -291,6 +330,18 @@
|
||||||
crypto.getRandomValues(loadSlice(sp + 8));
|
crypto.getRandomValues(loadSlice(sp + 8));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// func finalizeRef(v ref)
|
||||||
|
"syscall/js.finalizeRef": (sp) => {
|
||||||
|
const id = this.mem.getUint32(sp + 8, true);
|
||||||
|
this._goRefCounts[id]--;
|
||||||
|
if (this._goRefCounts[id] === 0) {
|
||||||
|
const v = this._values[id];
|
||||||
|
this._values[id] = null;
|
||||||
|
this._ids.delete(v);
|
||||||
|
this._idPool.push(id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// func stringVal(value string) ref
|
// func stringVal(value string) ref
|
||||||
"syscall/js.stringVal": (sp) => {
|
"syscall/js.stringVal": (sp) => {
|
||||||
storeValue(sp + 24, loadString(sp + 8));
|
storeValue(sp + 24, loadString(sp + 8));
|
||||||
|
|
@ -308,6 +359,11 @@
|
||||||
Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));
|
Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// func valueDelete(v ref, p string)
|
||||||
|
"syscall/js.valueDelete": (sp) => {
|
||||||
|
Reflect.deleteProperty(loadValue(sp + 8), loadString(sp + 16));
|
||||||
|
},
|
||||||
|
|
||||||
// func valueIndex(v ref, i int) ref
|
// func valueIndex(v ref, i int) ref
|
||||||
"syscall/js.valueIndex": (sp) => {
|
"syscall/js.valueIndex": (sp) => {
|
||||||
storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));
|
storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));
|
||||||
|
|
@ -327,10 +383,10 @@
|
||||||
const result = Reflect.apply(m, v, args);
|
const result = Reflect.apply(m, v, args);
|
||||||
sp = this._inst.exports.getsp(); // see comment above
|
sp = this._inst.exports.getsp(); // see comment above
|
||||||
storeValue(sp + 56, result);
|
storeValue(sp + 56, result);
|
||||||
mem().setUint8(sp + 64, 1);
|
this.mem.setUint8(sp + 64, 1);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
storeValue(sp + 56, err);
|
storeValue(sp + 56, err);
|
||||||
mem().setUint8(sp + 64, 0);
|
this.mem.setUint8(sp + 64, 0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -342,10 +398,10 @@
|
||||||
const result = Reflect.apply(v, undefined, args);
|
const result = Reflect.apply(v, undefined, args);
|
||||||
sp = this._inst.exports.getsp(); // see comment above
|
sp = this._inst.exports.getsp(); // see comment above
|
||||||
storeValue(sp + 40, result);
|
storeValue(sp + 40, result);
|
||||||
mem().setUint8(sp + 48, 1);
|
this.mem.setUint8(sp + 48, 1);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
storeValue(sp + 40, err);
|
storeValue(sp + 40, err);
|
||||||
mem().setUint8(sp + 48, 0);
|
this.mem.setUint8(sp + 48, 0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -357,10 +413,10 @@
|
||||||
const result = Reflect.construct(v, args);
|
const result = Reflect.construct(v, args);
|
||||||
sp = this._inst.exports.getsp(); // see comment above
|
sp = this._inst.exports.getsp(); // see comment above
|
||||||
storeValue(sp + 40, result);
|
storeValue(sp + 40, result);
|
||||||
mem().setUint8(sp + 48, 1);
|
this.mem.setUint8(sp + 48, 1);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
storeValue(sp + 40, err);
|
storeValue(sp + 40, err);
|
||||||
mem().setUint8(sp + 48, 0);
|
this.mem.setUint8(sp + 48, 0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -384,7 +440,7 @@
|
||||||
|
|
||||||
// func valueInstanceOf(v ref, t ref) bool
|
// func valueInstanceOf(v ref, t ref) bool
|
||||||
"syscall/js.valueInstanceOf": (sp) => {
|
"syscall/js.valueInstanceOf": (sp) => {
|
||||||
mem().setUint8(sp + 24, loadValue(sp + 8) instanceof loadValue(sp + 16));
|
this.mem.setUint8(sp + 24, loadValue(sp + 8) instanceof loadValue(sp + 16));
|
||||||
},
|
},
|
||||||
|
|
||||||
// func copyBytesToGo(dst []byte, src ref) (int, bool)
|
// func copyBytesToGo(dst []byte, src ref) (int, bool)
|
||||||
|
|
@ -392,13 +448,13 @@
|
||||||
const dst = loadSlice(sp + 8);
|
const dst = loadSlice(sp + 8);
|
||||||
const src = loadValue(sp + 32);
|
const src = loadValue(sp + 32);
|
||||||
if (!(src instanceof Uint8Array)) {
|
if (!(src instanceof Uint8Array)) {
|
||||||
mem().setUint8(sp + 48, 0);
|
this.mem.setUint8(sp + 48, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const toCopy = src.subarray(0, dst.length);
|
const toCopy = src.subarray(0, dst.length);
|
||||||
dst.set(toCopy);
|
dst.set(toCopy);
|
||||||
setInt64(sp + 40, toCopy.length);
|
setInt64(sp + 40, toCopy.length);
|
||||||
mem().setUint8(sp + 48, 1);
|
this.mem.setUint8(sp + 48, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
// func copyBytesToJS(dst ref, src []byte) (int, bool)
|
// func copyBytesToJS(dst ref, src []byte) (int, bool)
|
||||||
|
|
@ -406,13 +462,13 @@
|
||||||
const dst = loadValue(sp + 8);
|
const dst = loadValue(sp + 8);
|
||||||
const src = loadSlice(sp + 16);
|
const src = loadSlice(sp + 16);
|
||||||
if (!(dst instanceof Uint8Array)) {
|
if (!(dst instanceof Uint8Array)) {
|
||||||
mem().setUint8(sp + 48, 0);
|
this.mem.setUint8(sp + 48, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const toCopy = src.subarray(0, dst.length);
|
const toCopy = src.subarray(0, dst.length);
|
||||||
dst.set(toCopy);
|
dst.set(toCopy);
|
||||||
setInt64(sp + 40, toCopy.length);
|
setInt64(sp + 40, toCopy.length);
|
||||||
mem().setUint8(sp + 48, 1);
|
this.mem.setUint8(sp + 48, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
"debug": (value) => {
|
"debug": (value) => {
|
||||||
|
|
@ -424,7 +480,8 @@
|
||||||
|
|
||||||
async run(instance) {
|
async run(instance) {
|
||||||
this._inst = instance;
|
this._inst = instance;
|
||||||
this._values = [ // TODO: garbage collection
|
this.mem = new DataView(this._inst.exports.mem.buffer);
|
||||||
|
this._values = [ // JS values that Go currently has references to, indexed by reference id
|
||||||
NaN,
|
NaN,
|
||||||
0,
|
0,
|
||||||
null,
|
null,
|
||||||
|
|
@ -433,10 +490,10 @@
|
||||||
global,
|
global,
|
||||||
this,
|
this,
|
||||||
];
|
];
|
||||||
this._refs = new Map();
|
this._goRefCounts = []; // number of references that Go has to a JS value, indexed by reference id
|
||||||
this.exited = false;
|
this._ids = new Map(); // mapping from JS values to reference ids
|
||||||
|
this._idPool = []; // unused ids that have been garbage collected
|
||||||
const mem = new DataView(this._inst.exports.mem.buffer)
|
this.exited = false; // whether the Go program has exited
|
||||||
|
|
||||||
// Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
|
// Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
|
||||||
let offset = 4096;
|
let offset = 4096;
|
||||||
|
|
@ -444,7 +501,7 @@
|
||||||
const strPtr = (str) => {
|
const strPtr = (str) => {
|
||||||
const ptr = offset;
|
const ptr = offset;
|
||||||
const bytes = encoder.encode(str + "\0");
|
const bytes = encoder.encode(str + "\0");
|
||||||
new Uint8Array(mem.buffer, offset, bytes.length).set(bytes);
|
new Uint8Array(this.mem.buffer, offset, bytes.length).set(bytes);
|
||||||
offset += bytes.length;
|
offset += bytes.length;
|
||||||
if (offset % 8 !== 0) {
|
if (offset % 8 !== 0) {
|
||||||
offset += 8 - (offset % 8);
|
offset += 8 - (offset % 8);
|
||||||
|
|
@ -458,17 +515,18 @@
|
||||||
this.argv.forEach((arg) => {
|
this.argv.forEach((arg) => {
|
||||||
argvPtrs.push(strPtr(arg));
|
argvPtrs.push(strPtr(arg));
|
||||||
});
|
});
|
||||||
|
argvPtrs.push(0);
|
||||||
|
|
||||||
const keys = Object.keys(this.env).sort();
|
const keys = Object.keys(this.env).sort();
|
||||||
argvPtrs.push(keys.length);
|
|
||||||
keys.forEach((key) => {
|
keys.forEach((key) => {
|
||||||
argvPtrs.push(strPtr(`${key}=${this.env[key]}`));
|
argvPtrs.push(strPtr(`${key}=${this.env[key]}`));
|
||||||
});
|
});
|
||||||
|
argvPtrs.push(0);
|
||||||
|
|
||||||
const argv = offset;
|
const argv = offset;
|
||||||
argvPtrs.forEach((ptr) => {
|
argvPtrs.forEach((ptr) => {
|
||||||
mem.setUint32(offset, ptr, true);
|
this.mem.setUint32(offset, ptr, true);
|
||||||
mem.setUint32(offset + 4, 0, true);
|
this.mem.setUint32(offset + 4, 0, true);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -432,6 +432,7 @@ func (b *Reader) ReadBytes(delim byte) ([]byte, error) {
|
||||||
var frag []byte
|
var frag []byte
|
||||||
var full [][]byte
|
var full [][]byte
|
||||||
var err error
|
var err error
|
||||||
|
n := 0
|
||||||
for {
|
for {
|
||||||
var e error
|
var e error
|
||||||
frag, e = b.ReadSlice(delim)
|
frag, e = b.ReadSlice(delim)
|
||||||
|
|
@ -447,18 +448,15 @@ func (b *Reader) ReadBytes(delim byte) ([]byte, error) {
|
||||||
buf := make([]byte, len(frag))
|
buf := make([]byte, len(frag))
|
||||||
copy(buf, frag)
|
copy(buf, frag)
|
||||||
full = append(full, buf)
|
full = append(full, buf)
|
||||||
|
n += len(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate new buffer to hold the full pieces and the fragment.
|
|
||||||
n := 0
|
|
||||||
for i := range full {
|
|
||||||
n += len(full[i])
|
|
||||||
}
|
|
||||||
n += len(frag)
|
n += len(frag)
|
||||||
|
|
||||||
// Copy full pieces and fragment in.
|
// Allocate new buffer to hold the full pieces and the fragment.
|
||||||
buf := make([]byte, n)
|
buf := make([]byte, n)
|
||||||
n = 0
|
n = 0
|
||||||
|
// Copy full pieces and fragment in.
|
||||||
for i := range full {
|
for i := range full {
|
||||||
n += copy(buf[n:], full[i])
|
n += copy(buf[n:], full[i])
|
||||||
}
|
}
|
||||||
|
|
@ -708,9 +706,14 @@ func (b *Writer) WriteString(s string) (int, error) {
|
||||||
// supports the ReadFrom method, and b has no buffered data yet,
|
// supports the ReadFrom method, and b has no buffered data yet,
|
||||||
// this calls the underlying ReadFrom without buffering.
|
// this calls the underlying ReadFrom without buffering.
|
||||||
func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
|
func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
|
||||||
|
if b.err != nil {
|
||||||
|
return 0, b.err
|
||||||
|
}
|
||||||
if b.Buffered() == 0 {
|
if b.Buffered() == 0 {
|
||||||
if w, ok := b.wr.(io.ReaderFrom); ok {
|
if w, ok := b.wr.(io.ReaderFrom); ok {
|
||||||
return w.ReadFrom(r)
|
n, err = w.ReadFrom(r)
|
||||||
|
b.err = err
|
||||||
|
return n, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var m int
|
var m int
|
||||||
|
|
|
||||||
|
|
@ -1535,6 +1535,52 @@ func TestPartialReadEOF(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type writerWithReadFromError struct{}
|
||||||
|
|
||||||
|
func (w writerWithReadFromError) ReadFrom(r io.Reader) (int64, error) {
|
||||||
|
return 0, errors.New("writerWithReadFromError error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w writerWithReadFromError) Write(b []byte) (n int, err error) {
|
||||||
|
return 10, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriterReadFromMustSetUnderlyingError(t *testing.T) {
|
||||||
|
var wr = NewWriter(writerWithReadFromError{})
|
||||||
|
if _, err := wr.ReadFrom(strings.NewReader("test2")); err == nil {
|
||||||
|
t.Fatal("expected ReadFrom returns error, got nil")
|
||||||
|
}
|
||||||
|
if _, err := wr.Write([]byte("123")); err == nil {
|
||||||
|
t.Fatal("expected Write returns error, got nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type writeErrorOnlyWriter struct{}
|
||||||
|
|
||||||
|
func (w writeErrorOnlyWriter) Write(p []byte) (n int, err error) {
|
||||||
|
return 0, errors.New("writeErrorOnlyWriter error")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that previous Write errors are immediately returned
|
||||||
|
// on any ReadFrom. See golang.org/issue/35194.
|
||||||
|
func TestWriterReadFromMustReturnUnderlyingError(t *testing.T) {
|
||||||
|
var wr = NewWriter(writeErrorOnlyWriter{})
|
||||||
|
s := "test1"
|
||||||
|
wantBuffered := len(s)
|
||||||
|
if _, err := wr.WriteString(s); err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if err := wr.Flush(); err == nil {
|
||||||
|
t.Error("expected flush error, got nil")
|
||||||
|
}
|
||||||
|
if _, err := wr.ReadFrom(strings.NewReader("test2")); err == nil {
|
||||||
|
t.Fatal("expected error, got nil")
|
||||||
|
}
|
||||||
|
if buffered := wr.Buffered(); buffered != wantBuffered {
|
||||||
|
t.Fatalf("Buffered = %v; want %v", buffered, wantBuffered)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkReaderCopyOptimal(b *testing.B) {
|
func BenchmarkReaderCopyOptimal(b *testing.B) {
|
||||||
// Optimal case is where the underlying reader implements io.WriterTo
|
// Optimal case is where the underlying reader implements io.WriterTo
|
||||||
srcBuf := bytes.NewBuffer(make([]byte, 8192))
|
srcBuf := bytes.NewBuffer(make([]byte, 8192))
|
||||||
|
|
|
||||||
|
|
@ -45,17 +45,17 @@ selectedtargets() {
|
||||||
gettargets | egrep -v 'android-arm|darwin-arm' | egrep "$pattern"
|
gettargets | egrep -v 'android-arm|darwin-arm' | egrep "$pattern"
|
||||||
}
|
}
|
||||||
|
|
||||||
# put linux, nacl first in the target list to get all the architectures up front.
|
# put linux first in the target list to get all the architectures up front.
|
||||||
linux_nacl_targets() {
|
linux_targets() {
|
||||||
selectedtargets | egrep 'linux|nacl' | sort
|
selectedtargets | grep 'linux' | sort
|
||||||
}
|
}
|
||||||
|
|
||||||
non_linux_nacl_targets() {
|
non_linux_targets() {
|
||||||
selectedtargets | egrep -v 'linux|nacl' | sort
|
selectedtargets | grep -v 'linux' | sort
|
||||||
}
|
}
|
||||||
|
|
||||||
# Note words in $targets are separated by both newlines and spaces.
|
# Note words in $targets are separated by both newlines and spaces.
|
||||||
targets="$(linux_nacl_targets) $(non_linux_nacl_targets)"
|
targets="$(linux_targets) $(non_linux_targets)"
|
||||||
|
|
||||||
failed=false
|
failed=false
|
||||||
for target in $targets
|
for target in $targets
|
||||||
|
|
|
||||||
|
|
@ -935,7 +935,8 @@ func ReplaceAll(s, old, new []byte) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
// EqualFold reports whether s and t, interpreted as UTF-8 strings,
|
// EqualFold reports whether s and t, interpreted as UTF-8 strings,
|
||||||
// are equal under Unicode case-folding.
|
// are equal under Unicode case-folding, which is a more general
|
||||||
|
// form of case-insensitivity.
|
||||||
func EqualFold(s, t []byte) bool {
|
func EqualFold(s, t []byte) bool {
|
||||||
for len(s) != 0 && len(t) != 0 {
|
for len(s) != 0 && len(t) != 0 {
|
||||||
// Extract first rune from each.
|
// Extract first rune from each.
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,39 @@ func TestCompareBytes(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEndianBaseCompare(t *testing.T) {
|
||||||
|
// This test compares byte slices that are almost identical, except one
|
||||||
|
// difference that for some j, a[j]>b[j] and a[j+1]<b[j+1]. If the implementation
|
||||||
|
// compares large chunks with wrong endianness, it gets wrong result.
|
||||||
|
// no vector register is larger than 512 bytes for now
|
||||||
|
const maxLength = 512
|
||||||
|
a := make([]byte, maxLength)
|
||||||
|
b := make([]byte, maxLength)
|
||||||
|
// randomish but deterministic data. No 0 or 255.
|
||||||
|
for i := 0; i < maxLength; i++ {
|
||||||
|
a[i] = byte(1 + 31*i%254)
|
||||||
|
b[i] = byte(1 + 31*i%254)
|
||||||
|
}
|
||||||
|
for i := 2; i <= maxLength; i <<= 1 {
|
||||||
|
for j := 0; j < i-1; j++ {
|
||||||
|
a[j] = b[j] - 1
|
||||||
|
a[j+1] = b[j+1] + 1
|
||||||
|
cmp := Compare(a[:i], b[:i])
|
||||||
|
if cmp != -1 {
|
||||||
|
t.Errorf(`CompareBbigger(%d,%d) = %d`, i, j, cmp)
|
||||||
|
}
|
||||||
|
a[j] = b[j] + 1
|
||||||
|
a[j+1] = b[j+1] - 1
|
||||||
|
cmp = Compare(a[:i], b[:i])
|
||||||
|
if cmp != 1 {
|
||||||
|
t.Errorf(`CompareAbigger(%d,%d) = %d`, i, j, cmp)
|
||||||
|
}
|
||||||
|
a[j] = b[j]
|
||||||
|
a[j+1] = b[j+1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkCompareBytesEqual(b *testing.B) {
|
func BenchmarkCompareBytesEqual(b *testing.B) {
|
||||||
b1 := []byte("Hello Gophers!")
|
b1 := []byte("Hello Gophers!")
|
||||||
b2 := []byte("Hello Gophers!")
|
b2 := []byte("Hello Gophers!")
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"cmd/internal/obj/arm64"
|
"cmd/internal/obj/arm64"
|
||||||
"cmd/internal/obj/mips"
|
"cmd/internal/obj/mips"
|
||||||
"cmd/internal/obj/ppc64"
|
"cmd/internal/obj/ppc64"
|
||||||
|
"cmd/internal/obj/riscv"
|
||||||
"cmd/internal/obj/s390x"
|
"cmd/internal/obj/s390x"
|
||||||
"cmd/internal/obj/wasm"
|
"cmd/internal/obj/wasm"
|
||||||
"cmd/internal/obj/x86"
|
"cmd/internal/obj/x86"
|
||||||
|
|
@ -55,40 +56,26 @@ func Set(GOARCH string) *Arch {
|
||||||
return archX86(&x86.Link386)
|
return archX86(&x86.Link386)
|
||||||
case "amd64":
|
case "amd64":
|
||||||
return archX86(&x86.Linkamd64)
|
return archX86(&x86.Linkamd64)
|
||||||
case "amd64p32":
|
|
||||||
return archX86(&x86.Linkamd64p32)
|
|
||||||
case "arm":
|
case "arm":
|
||||||
return archArm()
|
return archArm()
|
||||||
case "arm64":
|
case "arm64":
|
||||||
return archArm64()
|
return archArm64()
|
||||||
case "mips":
|
case "mips":
|
||||||
a := archMips()
|
return archMips(&mips.Linkmips)
|
||||||
a.LinkArch = &mips.Linkmips
|
|
||||||
return a
|
|
||||||
case "mipsle":
|
case "mipsle":
|
||||||
a := archMips()
|
return archMips(&mips.Linkmipsle)
|
||||||
a.LinkArch = &mips.Linkmipsle
|
|
||||||
return a
|
|
||||||
case "mips64":
|
case "mips64":
|
||||||
a := archMips64()
|
return archMips64(&mips.Linkmips64)
|
||||||
a.LinkArch = &mips.Linkmips64
|
|
||||||
return a
|
|
||||||
case "mips64le":
|
case "mips64le":
|
||||||
a := archMips64()
|
return archMips64(&mips.Linkmips64le)
|
||||||
a.LinkArch = &mips.Linkmips64le
|
|
||||||
return a
|
|
||||||
case "ppc64":
|
case "ppc64":
|
||||||
a := archPPC64()
|
return archPPC64(&ppc64.Linkppc64)
|
||||||
a.LinkArch = &ppc64.Linkppc64
|
|
||||||
return a
|
|
||||||
case "ppc64le":
|
case "ppc64le":
|
||||||
a := archPPC64()
|
return archPPC64(&ppc64.Linkppc64le)
|
||||||
a.LinkArch = &ppc64.Linkppc64le
|
case "riscv64":
|
||||||
return a
|
return archRISCV64()
|
||||||
case "s390x":
|
case "s390x":
|
||||||
a := archS390x()
|
return archS390x()
|
||||||
a.LinkArch = &s390x.Links390x
|
|
||||||
return a
|
|
||||||
case "wasm":
|
case "wasm":
|
||||||
return archWasm()
|
return archWasm()
|
||||||
}
|
}
|
||||||
|
|
@ -99,6 +86,14 @@ func jumpX86(word string) bool {
|
||||||
return word[0] == 'J' || word == "CALL" || strings.HasPrefix(word, "LOOP") || word == "XBEGIN"
|
return word[0] == 'J' || word == "CALL" || strings.HasPrefix(word, "LOOP") || word == "XBEGIN"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func jumpRISCV(word string) bool {
|
||||||
|
switch word {
|
||||||
|
case "BEQ", "BNE", "BLT", "BGE", "BLTU", "BGEU", "CALL", "JAL", "JALR", "JMP":
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func jumpWasm(word string) bool {
|
func jumpWasm(word string) bool {
|
||||||
return word == "JMP" || word == "CALL" || word == "Call" || word == "Br" || word == "BrIf"
|
return word == "JMP" || word == "CALL" || word == "Call" || word == "Br" || word == "BrIf"
|
||||||
}
|
}
|
||||||
|
|
@ -267,21 +262,15 @@ func archArm64() *Arch {
|
||||||
for i := arm64.REG_V0; i <= arm64.REG_V31; i++ {
|
for i := arm64.REG_V0; i <= arm64.REG_V31; i++ {
|
||||||
register[obj.Rconv(i)] = int16(i)
|
register[obj.Rconv(i)] = int16(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// System registers.
|
||||||
|
for i := 0; i < len(arm64.SystemReg); i++ {
|
||||||
|
register[arm64.SystemReg[i].Name] = arm64.SystemReg[i].Reg
|
||||||
|
}
|
||||||
|
|
||||||
register["LR"] = arm64.REGLINK
|
register["LR"] = arm64.REGLINK
|
||||||
register["DAIF"] = arm64.REG_DAIF
|
|
||||||
register["NZCV"] = arm64.REG_NZCV
|
|
||||||
register["FPSR"] = arm64.REG_FPSR
|
|
||||||
register["FPCR"] = arm64.REG_FPCR
|
|
||||||
register["SPSR_EL1"] = arm64.REG_SPSR_EL1
|
|
||||||
register["ELR_EL1"] = arm64.REG_ELR_EL1
|
|
||||||
register["SPSR_EL2"] = arm64.REG_SPSR_EL2
|
|
||||||
register["ELR_EL2"] = arm64.REG_ELR_EL2
|
|
||||||
register["CurrentEL"] = arm64.REG_CurrentEL
|
|
||||||
register["SP_EL0"] = arm64.REG_SP_EL0
|
|
||||||
register["SPSel"] = arm64.REG_SPSel
|
|
||||||
register["DAIFSet"] = arm64.REG_DAIFSet
|
register["DAIFSet"] = arm64.REG_DAIFSet
|
||||||
register["DAIFClr"] = arm64.REG_DAIFClr
|
register["DAIFClr"] = arm64.REG_DAIFClr
|
||||||
register["DCZID_EL0"] = arm64.REG_DCZID_EL0
|
|
||||||
register["PLDL1KEEP"] = arm64.REG_PLDL1KEEP
|
register["PLDL1KEEP"] = arm64.REG_PLDL1KEEP
|
||||||
register["PLDL1STRM"] = arm64.REG_PLDL1STRM
|
register["PLDL1STRM"] = arm64.REG_PLDL1STRM
|
||||||
register["PLDL2KEEP"] = arm64.REG_PLDL2KEEP
|
register["PLDL2KEEP"] = arm64.REG_PLDL2KEEP
|
||||||
|
|
@ -358,7 +347,7 @@ func archArm64() *Arch {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func archPPC64() *Arch {
|
func archPPC64(linkArch *obj.LinkArch) *Arch {
|
||||||
register := make(map[string]int16)
|
register := make(map[string]int16)
|
||||||
// Create maps for easy lookup of instruction names etc.
|
// Create maps for easy lookup of instruction names etc.
|
||||||
// Note that there is no list of names as there is for x86.
|
// Note that there is no list of names as there is for x86.
|
||||||
|
|
@ -414,7 +403,7 @@ func archPPC64() *Arch {
|
||||||
instructions["BL"] = ppc64.ABL
|
instructions["BL"] = ppc64.ABL
|
||||||
|
|
||||||
return &Arch{
|
return &Arch{
|
||||||
LinkArch: &ppc64.Linkppc64,
|
LinkArch: linkArch,
|
||||||
Instructions: instructions,
|
Instructions: instructions,
|
||||||
Register: register,
|
Register: register,
|
||||||
RegisterPrefix: registerPrefix,
|
RegisterPrefix: registerPrefix,
|
||||||
|
|
@ -423,7 +412,7 @@ func archPPC64() *Arch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func archMips() *Arch {
|
func archMips(linkArch *obj.LinkArch) *Arch {
|
||||||
register := make(map[string]int16)
|
register := make(map[string]int16)
|
||||||
// Create maps for easy lookup of instruction names etc.
|
// Create maps for easy lookup of instruction names etc.
|
||||||
// Note that there is no list of names as there is for x86.
|
// Note that there is no list of names as there is for x86.
|
||||||
|
|
@ -470,7 +459,7 @@ func archMips() *Arch {
|
||||||
instructions["JAL"] = mips.AJAL
|
instructions["JAL"] = mips.AJAL
|
||||||
|
|
||||||
return &Arch{
|
return &Arch{
|
||||||
LinkArch: &mips.Linkmipsle,
|
LinkArch: linkArch,
|
||||||
Instructions: instructions,
|
Instructions: instructions,
|
||||||
Register: register,
|
Register: register,
|
||||||
RegisterPrefix: registerPrefix,
|
RegisterPrefix: registerPrefix,
|
||||||
|
|
@ -479,7 +468,7 @@ func archMips() *Arch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func archMips64() *Arch {
|
func archMips64(linkArch *obj.LinkArch) *Arch {
|
||||||
register := make(map[string]int16)
|
register := make(map[string]int16)
|
||||||
// Create maps for easy lookup of instruction names etc.
|
// Create maps for easy lookup of instruction names etc.
|
||||||
// Note that there is no list of names as there is for x86.
|
// Note that there is no list of names as there is for x86.
|
||||||
|
|
@ -527,7 +516,7 @@ func archMips64() *Arch {
|
||||||
instructions["JAL"] = mips.AJAL
|
instructions["JAL"] = mips.AJAL
|
||||||
|
|
||||||
return &Arch{
|
return &Arch{
|
||||||
LinkArch: &mips.Linkmips64,
|
LinkArch: linkArch,
|
||||||
Instructions: instructions,
|
Instructions: instructions,
|
||||||
Register: register,
|
Register: register,
|
||||||
RegisterPrefix: registerPrefix,
|
RegisterPrefix: registerPrefix,
|
||||||
|
|
@ -536,6 +525,117 @@ func archMips64() *Arch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func archRISCV64() *Arch {
|
||||||
|
register := make(map[string]int16)
|
||||||
|
|
||||||
|
// Standard register names.
|
||||||
|
for i := riscv.REG_X0; i <= riscv.REG_X31; i++ {
|
||||||
|
name := fmt.Sprintf("X%d", i-riscv.REG_X0)
|
||||||
|
register[name] = int16(i)
|
||||||
|
}
|
||||||
|
for i := riscv.REG_F0; i <= riscv.REG_F31; i++ {
|
||||||
|
name := fmt.Sprintf("F%d", i-riscv.REG_F0)
|
||||||
|
register[name] = int16(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// General registers with ABI names.
|
||||||
|
register["ZERO"] = riscv.REG_ZERO
|
||||||
|
register["RA"] = riscv.REG_RA
|
||||||
|
register["SP"] = riscv.REG_SP
|
||||||
|
register["GP"] = riscv.REG_GP
|
||||||
|
register["TP"] = riscv.REG_TP
|
||||||
|
register["T0"] = riscv.REG_T0
|
||||||
|
register["T1"] = riscv.REG_T1
|
||||||
|
register["T2"] = riscv.REG_T2
|
||||||
|
register["S0"] = riscv.REG_S0
|
||||||
|
register["S1"] = riscv.REG_S1
|
||||||
|
register["A0"] = riscv.REG_A0
|
||||||
|
register["A1"] = riscv.REG_A1
|
||||||
|
register["A2"] = riscv.REG_A2
|
||||||
|
register["A3"] = riscv.REG_A3
|
||||||
|
register["A4"] = riscv.REG_A4
|
||||||
|
register["A5"] = riscv.REG_A5
|
||||||
|
register["A6"] = riscv.REG_A6
|
||||||
|
register["A7"] = riscv.REG_A7
|
||||||
|
register["S2"] = riscv.REG_S2
|
||||||
|
register["S3"] = riscv.REG_S3
|
||||||
|
register["S4"] = riscv.REG_S4
|
||||||
|
register["S5"] = riscv.REG_S5
|
||||||
|
register["S6"] = riscv.REG_S6
|
||||||
|
register["S7"] = riscv.REG_S7
|
||||||
|
register["S8"] = riscv.REG_S8
|
||||||
|
register["S9"] = riscv.REG_S9
|
||||||
|
register["S10"] = riscv.REG_S10
|
||||||
|
register["S11"] = riscv.REG_S11
|
||||||
|
register["T3"] = riscv.REG_T3
|
||||||
|
register["T4"] = riscv.REG_T4
|
||||||
|
register["T5"] = riscv.REG_T5
|
||||||
|
register["T6"] = riscv.REG_T6
|
||||||
|
|
||||||
|
// Go runtime register names.
|
||||||
|
register["g"] = riscv.REG_G
|
||||||
|
register["CTXT"] = riscv.REG_CTXT
|
||||||
|
register["TMP"] = riscv.REG_TMP
|
||||||
|
|
||||||
|
// ABI names for floating point register.
|
||||||
|
register["FT0"] = riscv.REG_FT0
|
||||||
|
register["FT1"] = riscv.REG_FT1
|
||||||
|
register["FT2"] = riscv.REG_FT2
|
||||||
|
register["FT3"] = riscv.REG_FT3
|
||||||
|
register["FT4"] = riscv.REG_FT4
|
||||||
|
register["FT5"] = riscv.REG_FT5
|
||||||
|
register["FT6"] = riscv.REG_FT6
|
||||||
|
register["FT7"] = riscv.REG_FT7
|
||||||
|
register["FS0"] = riscv.REG_FS0
|
||||||
|
register["FS1"] = riscv.REG_FS1
|
||||||
|
register["FA0"] = riscv.REG_FA0
|
||||||
|
register["FA1"] = riscv.REG_FA1
|
||||||
|
register["FA2"] = riscv.REG_FA2
|
||||||
|
register["FA3"] = riscv.REG_FA3
|
||||||
|
register["FA4"] = riscv.REG_FA4
|
||||||
|
register["FA5"] = riscv.REG_FA5
|
||||||
|
register["FA6"] = riscv.REG_FA6
|
||||||
|
register["FA7"] = riscv.REG_FA7
|
||||||
|
register["FS2"] = riscv.REG_FS2
|
||||||
|
register["FS3"] = riscv.REG_FS3
|
||||||
|
register["FS4"] = riscv.REG_FS4
|
||||||
|
register["FS5"] = riscv.REG_FS5
|
||||||
|
register["FS6"] = riscv.REG_FS6
|
||||||
|
register["FS7"] = riscv.REG_FS7
|
||||||
|
register["FS8"] = riscv.REG_FS8
|
||||||
|
register["FS9"] = riscv.REG_FS9
|
||||||
|
register["FS10"] = riscv.REG_FS10
|
||||||
|
register["FS11"] = riscv.REG_FS11
|
||||||
|
register["FT8"] = riscv.REG_FT8
|
||||||
|
register["FT9"] = riscv.REG_FT9
|
||||||
|
register["FT10"] = riscv.REG_FT10
|
||||||
|
register["FT11"] = riscv.REG_FT11
|
||||||
|
|
||||||
|
// Pseudo-registers.
|
||||||
|
register["SB"] = RSB
|
||||||
|
register["FP"] = RFP
|
||||||
|
register["PC"] = RPC
|
||||||
|
|
||||||
|
instructions := make(map[string]obj.As)
|
||||||
|
for i, s := range obj.Anames {
|
||||||
|
instructions[s] = obj.As(i)
|
||||||
|
}
|
||||||
|
for i, s := range riscv.Anames {
|
||||||
|
if obj.As(i) >= obj.A_ARCHSPECIFIC {
|
||||||
|
instructions[s] = obj.As(i) + obj.ABaseRISCV
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Arch{
|
||||||
|
LinkArch: &riscv.LinkRISCV64,
|
||||||
|
Instructions: instructions,
|
||||||
|
Register: register,
|
||||||
|
RegisterPrefix: nil,
|
||||||
|
RegisterNumber: nilRegisterNumber,
|
||||||
|
IsJump: jumpRISCV,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func archS390x() *Arch {
|
func archS390x() *Arch {
|
||||||
register := make(map[string]int16)
|
register := make(map[string]int16)
|
||||||
// Create maps for easy lookup of instruction names etc.
|
// Create maps for easy lookup of instruction names etc.
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ func IsPPC64ISEL(op obj.As) bool {
|
||||||
// one of the CMP instructions that require special handling.
|
// one of the CMP instructions that require special handling.
|
||||||
func IsPPC64CMP(op obj.As) bool {
|
func IsPPC64CMP(op obj.As) bool {
|
||||||
switch op {
|
switch op {
|
||||||
case ppc64.ACMP, ppc64.ACMPU, ppc64.ACMPW, ppc64.ACMPWU:
|
case ppc64.ACMP, ppc64.ACMPU, ppc64.ACMPW, ppc64.ACMPWU, ppc64.AFCMPU:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,13 @@
|
||||||
package arch
|
package arch
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/internal/obj"
|
|
||||||
"cmd/internal/obj/s390x"
|
"cmd/internal/obj/s390x"
|
||||||
)
|
)
|
||||||
|
|
||||||
func jumpS390x(word string) bool {
|
func jumpS390x(word string) bool {
|
||||||
switch word {
|
switch word {
|
||||||
case "BC",
|
case "BRC",
|
||||||
|
"BC",
|
||||||
"BCL",
|
"BCL",
|
||||||
"BEQ",
|
"BEQ",
|
||||||
"BGE",
|
"BGE",
|
||||||
|
|
@ -29,6 +29,8 @@ func jumpS390x(word string) bool {
|
||||||
"BR",
|
"BR",
|
||||||
"BVC",
|
"BVC",
|
||||||
"BVS",
|
"BVS",
|
||||||
|
"BRCT",
|
||||||
|
"BRCTG",
|
||||||
"CMPBEQ",
|
"CMPBEQ",
|
||||||
"CMPBGE",
|
"CMPBGE",
|
||||||
"CMPBGT",
|
"CMPBGT",
|
||||||
|
|
@ -41,6 +43,14 @@ func jumpS390x(word string) bool {
|
||||||
"CMPUBLE",
|
"CMPUBLE",
|
||||||
"CMPUBLT",
|
"CMPUBLT",
|
||||||
"CMPUBNE",
|
"CMPUBNE",
|
||||||
|
"CRJ",
|
||||||
|
"CGRJ",
|
||||||
|
"CLRJ",
|
||||||
|
"CLGRJ",
|
||||||
|
"CIJ",
|
||||||
|
"CGIJ",
|
||||||
|
"CLIJ",
|
||||||
|
"CLGIJ",
|
||||||
"CALL",
|
"CALL",
|
||||||
"JMP":
|
"JMP":
|
||||||
return true
|
return true
|
||||||
|
|
@ -48,26 +58,6 @@ func jumpS390x(word string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsS390xCMP reports whether the op (as defined by an s390x.A* constant) is
|
|
||||||
// one of the CMP instructions that require special handling.
|
|
||||||
func IsS390xCMP(op obj.As) bool {
|
|
||||||
switch op {
|
|
||||||
case s390x.ACMP, s390x.ACMPU, s390x.ACMPW, s390x.ACMPWU:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsS390xNEG reports whether the op (as defined by an s390x.A* constant) is
|
|
||||||
// one of the NEG-like instructions that require special handling.
|
|
||||||
func IsS390xNEG(op obj.As) bool {
|
|
||||||
switch op {
|
|
||||||
case s390x.ANEG, s390x.ANEGW:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func s390xRegisterNumber(name string, n int16) (int16, bool) {
|
func s390xRegisterNumber(name string, n int16) (int16, bool) {
|
||||||
switch name {
|
switch name {
|
||||||
case "AR":
|
case "AR":
|
||||||
|
|
|
||||||
|
|
@ -417,7 +417,7 @@ func (p *Parser) asmJump(op obj.As, cond string, a []obj.Addr) {
|
||||||
prog.Reg = reg
|
prog.Reg = reg
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if p.arch.Family == sys.MIPS || p.arch.Family == sys.MIPS64 {
|
if p.arch.Family == sys.MIPS || p.arch.Family == sys.MIPS64 || p.arch.Family == sys.RISCV64 {
|
||||||
// 3-operand jumps.
|
// 3-operand jumps.
|
||||||
// First two must be registers
|
// First two must be registers
|
||||||
target = &a[2]
|
target = &a[2]
|
||||||
|
|
@ -450,8 +450,19 @@ func (p *Parser) asmJump(op obj.As, cond string, a []obj.Addr) {
|
||||||
target = &a[2]
|
target = &a[2]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
p.errorf("wrong number of arguments to %s instruction", op)
|
||||||
fallthrough
|
return
|
||||||
|
case 4:
|
||||||
|
if p.arch.Family == sys.S390X {
|
||||||
|
// 4-operand compare-and-branch.
|
||||||
|
prog.From = a[0]
|
||||||
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
|
prog.SetFrom3(a[2])
|
||||||
|
target = &a[3]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
p.errorf("wrong number of arguments to %s instruction", op)
|
||||||
|
return
|
||||||
default:
|
default:
|
||||||
p.errorf("wrong number of arguments to %s instruction", op)
|
p.errorf("wrong number of arguments to %s instruction", op)
|
||||||
return
|
return
|
||||||
|
|
@ -579,7 +590,7 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||||
prog.To = a[1]
|
prog.To = a[1]
|
||||||
case 3:
|
case 3:
|
||||||
switch p.arch.Family {
|
switch p.arch.Family {
|
||||||
case sys.MIPS, sys.MIPS64:
|
case sys.MIPS, sys.MIPS64, sys.RISCV64:
|
||||||
prog.From = a[0]
|
prog.From = a[0]
|
||||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||||
prog.To = a[2]
|
prog.To = a[2]
|
||||||
|
|
|
||||||
|
|
@ -441,6 +441,10 @@ func TestPPC64Encoder(t *testing.T) {
|
||||||
testEndToEnd(t, "ppc64", "ppc64enc")
|
testEndToEnd(t, "ppc64", "ppc64enc")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRISCVEncoder(t *testing.T) {
|
||||||
|
testEndToEnd(t, "riscv64", "riscvenc")
|
||||||
|
}
|
||||||
|
|
||||||
func TestS390XEndToEnd(t *testing.T) {
|
func TestS390XEndToEnd(t *testing.T) {
|
||||||
testEndToEnd(t, "s390x", "s390x")
|
testEndToEnd(t, "s390x", "s390x")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1049,5 +1049,11 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
||||||
VADDPD Z2, Z9, Z21 // 62e1b54858ea
|
VADDPD Z2, Z9, Z21 // 62e1b54858ea
|
||||||
VADDPD Z21, Z2, Z9 // 6231ed4858cd
|
VADDPD Z21, Z2, Z9 // 6231ed4858cd
|
||||||
VADDPD Z9, Z21, Z2 // 62d1d54058d1
|
VADDPD Z9, Z21, Z2 // 62d1d54058d1
|
||||||
|
|
||||||
|
CLWB (BX) // 660fae33
|
||||||
|
CLDEMOTE (BX) // 0f1c03
|
||||||
|
TPAUSE BX // 660faef3
|
||||||
|
UMONITOR BX // f30faef3
|
||||||
|
UMWAIT BX // f20faef3
|
||||||
// End of tests.
|
// End of tests.
|
||||||
RET
|
RET
|
||||||
|
|
|
||||||
|
|
@ -132,4 +132,12 @@ TEXT errors(SB),$0
|
||||||
VADDPD.BCST X3, X2, K1, X1 // ERROR "illegal broadcast without memory argument"
|
VADDPD.BCST X3, X2, K1, X1 // ERROR "illegal broadcast without memory argument"
|
||||||
VADDPD.BCST X3, X2, K1, X1 // ERROR "illegal broadcast without memory argument"
|
VADDPD.BCST X3, X2, K1, X1 // ERROR "illegal broadcast without memory argument"
|
||||||
VADDPD.BCST X3, X2, K1, X1 // ERROR "illegal broadcast without memory argument"
|
VADDPD.BCST X3, X2, K1, X1 // ERROR "illegal broadcast without memory argument"
|
||||||
|
// CLWB instuctions:
|
||||||
|
CLWB BX // ERROR "invalid instruction"
|
||||||
|
// CLDEMOTE instructions:
|
||||||
|
CLDEMOTE BX // ERROR "invalid instruction"
|
||||||
|
// WAITPKG instructions:
|
||||||
|
TPAUSE (BX) // ERROR "invalid instruction"
|
||||||
|
UMONITOR (BX) // ERROR "invalid instruction"
|
||||||
|
UMWAIT (BX) // ERROR "invalid instruction"
|
||||||
RET
|
RET
|
||||||
|
|
|
||||||
593
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
593
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
|
|
@ -343,6 +343,27 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
|
||||||
VST1 [V0.S4, V1.S4], (R0) // 00a8004c
|
VST1 [V0.S4, V1.S4], (R0) // 00a8004c
|
||||||
VLD1 (R30), [V15.S2, V16.S2] // cfab400c
|
VLD1 (R30), [V15.S2, V16.S2] // cfab400c
|
||||||
VLD1.P 24(R30), [V3.S2,V4.S2,V5.S2] // c36bdf0c
|
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
|
||||||
|
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
|
||||||
|
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
|
||||||
|
VLD1R (R0), [V0.B16] // 00c0404d
|
||||||
|
VLD1R.P 16(R0), [V0.B16] // 00c0df4d
|
||||||
|
VLD1R.P (R15)(R1), [V15.H4] // VLD1R.P (R15)(R1*1), [V15.H4] // efc5c10d
|
||||||
|
VLD2R (R15), [V15.H4, V16.H4] // efc5600d
|
||||||
|
VLD2R.P 32(R0), [V0.D2, V1.D2] // 00ccff4d
|
||||||
|
VLD2R.P (R0)(R5), [V31.D1, V0.D1] // VLD2R.P (R0)(R5*1), [V31.D1, V0.D1] // 1fcce50d
|
||||||
|
VLD3R (RSP), [V31.S2, V0.S2, V1.S2] // ffeb400d
|
||||||
|
VLD3R.P 24(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
|
||||||
|
VLD4R (R0), [V0.B8, V1.B8, V2.B8, V3.B8] // 00e0600d
|
||||||
|
VLD4R.P 64(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
|
||||||
VST1.P [V24.S2], 8(R2) // 58789f0c
|
VST1.P [V24.S2], 8(R2) // 58789f0c
|
||||||
VST1 [V29.S2, V30.S2], (R29) // bdab000c
|
VST1 [V29.S2, V30.S2], (R29) // bdab000c
|
||||||
VST1 [V14.H4, V15.H4, V16.H4], (R27) // 6e67000c
|
VST1 [V14.H4, V15.H4, V16.H4], (R27) // 6e67000c
|
||||||
|
|
@ -352,6 +373,15 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
|
||||||
VST1.P V4.D[1], 8(R0) // 04849f4d
|
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) // VST1.P V4.D[1], (R0)(R1*1) // 0484814d
|
||||||
VST1 V4.D[1], (R0) // 0484004d
|
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
|
||||||
|
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
|
||||||
|
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
|
||||||
FMOVS F20, (R0) // 140000bd
|
FMOVS F20, (R0) // 140000bd
|
||||||
FMOVS.P F20, 4(R0) // 144400bc
|
FMOVS.P F20, 4(R0) // 144400bc
|
||||||
FMOVS.W F20, 4(R0) // 144c00bc
|
FMOVS.W F20, 4(R0) // 144c00bc
|
||||||
|
|
@ -1008,6 +1038,569 @@ again:
|
||||||
FSTPS (F3, F4), 1024(RSP) // fb0310916313002d
|
FSTPS (F3, F4), 1024(RSP) // fb0310916313002d
|
||||||
FSTPS (F3, F4), x(SB)
|
FSTPS (F3, F4), x(SB)
|
||||||
FSTPS (F3, F4), x+8(SB)
|
FSTPS (F3, F4), x+8(SB)
|
||||||
|
NOOP // 1f2003d5
|
||||||
|
HINT $0 // 1f2003d5
|
||||||
|
|
||||||
|
// System Register
|
||||||
|
MSR $1, SPSel // bf4100d5
|
||||||
|
MSR $9, DAIFSet // df4903d5
|
||||||
|
MSR $6, DAIFClr // ff4603d5
|
||||||
|
MRS ELR_EL1, R8 // 284038d5
|
||||||
|
MSR R16, ELR_EL1 // 304018d5
|
||||||
|
MSR R2, ACTLR_EL1 // 221018d5
|
||||||
|
MRS TCR_EL1, R5 // 452038d5
|
||||||
|
MRS PMEVCNTR15_EL0, R12 // ece93bd5
|
||||||
|
MSR R20, PMEVTYPER26_EL0 // 54ef1bd5
|
||||||
|
MSR R10, DBGBCR15_EL1 // aa0f10d5
|
||||||
|
MRS ACTLR_EL1, R3 // 231038d5
|
||||||
|
MSR R9, ACTLR_EL1 // 291018d5
|
||||||
|
MRS AFSR0_EL1, R10 // 0a5138d5
|
||||||
|
MSR R1, AFSR0_EL1 // 015118d5
|
||||||
|
MRS AFSR0_EL1, R9 // 095138d5
|
||||||
|
MSR R30, AFSR0_EL1 // 1e5118d5
|
||||||
|
MRS AFSR1_EL1, R0 // 205138d5
|
||||||
|
MSR R1, AFSR1_EL1 // 215118d5
|
||||||
|
MRS AFSR1_EL1, R8 // 285138d5
|
||||||
|
MSR R19, AFSR1_EL1 // 335118d5
|
||||||
|
MRS AIDR_EL1, R11 // eb0039d5
|
||||||
|
MRS AMAIR_EL1, R0 // 00a338d5
|
||||||
|
MSR R22, AMAIR_EL1 // 16a318d5
|
||||||
|
MRS AMAIR_EL1, R14 // 0ea338d5
|
||||||
|
MSR R0, AMAIR_EL1 // 00a318d5
|
||||||
|
MRS APDAKeyHi_EL1, R16 // 302238d5
|
||||||
|
MSR R26, APDAKeyHi_EL1 // 3a2218d5
|
||||||
|
MRS APDAKeyLo_EL1, R21 // 152238d5
|
||||||
|
MSR R22, APDAKeyLo_EL1 // 162218d5
|
||||||
|
MRS APDBKeyHi_EL1, R2 // 622238d5
|
||||||
|
MSR R6, APDBKeyHi_EL1 // 662218d5
|
||||||
|
MRS APDBKeyLo_EL1, R5 // 452238d5
|
||||||
|
MSR R22, APDBKeyLo_EL1 // 562218d5
|
||||||
|
MRS APGAKeyHi_EL1, R22 // 362338d5
|
||||||
|
MSR R5, APGAKeyHi_EL1 // 252318d5
|
||||||
|
MRS APGAKeyLo_EL1, R16 // 102338d5
|
||||||
|
MSR R22, APGAKeyLo_EL1 // 162318d5
|
||||||
|
MRS APIAKeyHi_EL1, R23 // 372138d5
|
||||||
|
MSR R17, APIAKeyHi_EL1 // 312118d5
|
||||||
|
MRS APIAKeyLo_EL1, R16 // 102138d5
|
||||||
|
MSR R6, APIAKeyLo_EL1 // 062118d5
|
||||||
|
MRS APIBKeyHi_EL1, R10 // 6a2138d5
|
||||||
|
MSR R11, APIBKeyHi_EL1 // 6b2118d5
|
||||||
|
MRS APIBKeyLo_EL1, R25 // 592138d5
|
||||||
|
MSR R22, APIBKeyLo_EL1 // 562118d5
|
||||||
|
MRS CCSIDR_EL1, R25 // 190039d5
|
||||||
|
MRS CLIDR_EL1, R16 // 300039d5
|
||||||
|
MRS CNTFRQ_EL0, R20 // 14e03bd5
|
||||||
|
MSR R16, CNTFRQ_EL0 // 10e01bd5
|
||||||
|
MRS CNTKCTL_EL1, R26 // 1ae138d5
|
||||||
|
MSR R0, CNTKCTL_EL1 // 00e118d5
|
||||||
|
MRS CNTP_CTL_EL0, R14 // 2ee23bd5
|
||||||
|
MSR R17, CNTP_CTL_EL0 // 31e21bd5
|
||||||
|
MRS CNTP_CVAL_EL0, R15 // 4fe23bd5
|
||||||
|
MSR R8, CNTP_CVAL_EL0 // 48e21bd5
|
||||||
|
MRS CNTP_TVAL_EL0, R6 // 06e23bd5
|
||||||
|
MSR R29, CNTP_TVAL_EL0 // 1de21bd5
|
||||||
|
MRS CNTP_CTL_EL0, R22 // 36e23bd5
|
||||||
|
MSR R0, CNTP_CTL_EL0 // 20e21bd5
|
||||||
|
MRS CNTP_CVAL_EL0, R9 // 49e23bd5
|
||||||
|
MSR R4, CNTP_CVAL_EL0 // 44e21bd5
|
||||||
|
MRS CNTP_TVAL_EL0, R27 // 1be23bd5
|
||||||
|
MSR R17, CNTP_TVAL_EL0 // 11e21bd5
|
||||||
|
MRS CNTV_CTL_EL0, R27 // 3be33bd5
|
||||||
|
MSR R2, CNTV_CTL_EL0 // 22e31bd5
|
||||||
|
MRS CNTV_CVAL_EL0, R16 // 50e33bd5
|
||||||
|
MSR R27, CNTV_CVAL_EL0 // 5be31bd5
|
||||||
|
MRS CNTV_TVAL_EL0, R12 // 0ce33bd5
|
||||||
|
MSR R19, CNTV_TVAL_EL0 // 13e31bd5
|
||||||
|
MRS CNTV_CTL_EL0, R14 // 2ee33bd5
|
||||||
|
MSR R2, CNTV_CTL_EL0 // 22e31bd5
|
||||||
|
MRS CNTV_CVAL_EL0, R8 // 48e33bd5
|
||||||
|
MSR R26, CNTV_CVAL_EL0 // 5ae31bd5
|
||||||
|
MRS CNTV_TVAL_EL0, R6 // 06e33bd5
|
||||||
|
MSR R19, CNTV_TVAL_EL0 // 13e31bd5
|
||||||
|
MRS CNTKCTL_EL1, R16 // 10e138d5
|
||||||
|
MSR R26, CNTKCTL_EL1 // 1ae118d5
|
||||||
|
MRS CNTPCT_EL0, R9 // 29e03bd5
|
||||||
|
MRS CNTPS_CTL_EL1, R30 // 3ee23fd5
|
||||||
|
MSR R26, CNTPS_CTL_EL1 // 3ae21fd5
|
||||||
|
MRS CNTPS_CVAL_EL1, R8 // 48e23fd5
|
||||||
|
MSR R26, CNTPS_CVAL_EL1 // 5ae21fd5
|
||||||
|
MRS CNTPS_TVAL_EL1, R7 // 07e23fd5
|
||||||
|
MSR R13, CNTPS_TVAL_EL1 // 0de21fd5
|
||||||
|
MRS CNTP_CTL_EL0, R2 // 22e23bd5
|
||||||
|
MSR R10, CNTP_CTL_EL0 // 2ae21bd5
|
||||||
|
MRS CNTP_CVAL_EL0, R6 // 46e23bd5
|
||||||
|
MSR R21, CNTP_CVAL_EL0 // 55e21bd5
|
||||||
|
MRS CNTP_TVAL_EL0, R27 // 1be23bd5
|
||||||
|
MSR R29, CNTP_TVAL_EL0 // 1de21bd5
|
||||||
|
MRS CNTVCT_EL0, R13 // 4de03bd5
|
||||||
|
MRS CNTV_CTL_EL0, R30 // 3ee33bd5
|
||||||
|
MSR R19, CNTV_CTL_EL0 // 33e31bd5
|
||||||
|
MRS CNTV_CVAL_EL0, R27 // 5be33bd5
|
||||||
|
MSR R24, CNTV_CVAL_EL0 // 58e31bd5
|
||||||
|
MRS CNTV_TVAL_EL0, R24 // 18e33bd5
|
||||||
|
MSR R5, CNTV_TVAL_EL0 // 05e31bd5
|
||||||
|
MRS CONTEXTIDR_EL1, R15 // 2fd038d5
|
||||||
|
MSR R27, CONTEXTIDR_EL1 // 3bd018d5
|
||||||
|
MRS CONTEXTIDR_EL1, R29 // 3dd038d5
|
||||||
|
MSR R24, CONTEXTIDR_EL1 // 38d018d5
|
||||||
|
MRS CPACR_EL1, R10 // 4a1038d5
|
||||||
|
MSR R14, CPACR_EL1 // 4e1018d5
|
||||||
|
MRS CPACR_EL1, R27 // 5b1038d5
|
||||||
|
MSR R22, CPACR_EL1 // 561018d5
|
||||||
|
MRS CSSELR_EL1, R3 // 03003ad5
|
||||||
|
MSR R4, CSSELR_EL1 // 04001ad5
|
||||||
|
MRS CTR_EL0, R15 // 2f003bd5
|
||||||
|
MRS CurrentEL, R1 // 414238d5
|
||||||
|
MRS DAIF, R24 // 38423bd5
|
||||||
|
MSR R9, DAIF // 29421bd5
|
||||||
|
MRS DBGAUTHSTATUS_EL1, R5 // c57e30d5
|
||||||
|
MRS DBGBCR0_EL1, R29 // bd0030d5
|
||||||
|
MRS DBGBCR1_EL1, R13 // ad0130d5
|
||||||
|
MRS DBGBCR2_EL1, R22 // b60230d5
|
||||||
|
MRS DBGBCR3_EL1, R8 // a80330d5
|
||||||
|
MRS DBGBCR4_EL1, R2 // a20430d5
|
||||||
|
MRS DBGBCR5_EL1, R4 // a40530d5
|
||||||
|
MRS DBGBCR6_EL1, R2 // a20630d5
|
||||||
|
MRS DBGBCR7_EL1, R6 // a60730d5
|
||||||
|
MRS DBGBCR8_EL1, R1 // a10830d5
|
||||||
|
MRS DBGBCR9_EL1, R16 // b00930d5
|
||||||
|
MRS DBGBCR10_EL1, R23 // b70a30d5
|
||||||
|
MRS DBGBCR11_EL1, R3 // a30b30d5
|
||||||
|
MRS DBGBCR12_EL1, R6 // a60c30d5
|
||||||
|
MRS DBGBCR13_EL1, R16 // b00d30d5
|
||||||
|
MRS DBGBCR14_EL1, R4 // a40e30d5
|
||||||
|
MRS DBGBCR15_EL1, R9 // a90f30d5
|
||||||
|
MSR R4, DBGBCR0_EL1 // a40010d5
|
||||||
|
MSR R14, DBGBCR1_EL1 // ae0110d5
|
||||||
|
MSR R7, DBGBCR2_EL1 // a70210d5
|
||||||
|
MSR R12, DBGBCR3_EL1 // ac0310d5
|
||||||
|
MSR R6, DBGBCR4_EL1 // a60410d5
|
||||||
|
MSR R11, DBGBCR5_EL1 // ab0510d5
|
||||||
|
MSR R6, DBGBCR6_EL1 // a60610d5
|
||||||
|
MSR R13, DBGBCR7_EL1 // ad0710d5
|
||||||
|
MSR R17, DBGBCR8_EL1 // b10810d5
|
||||||
|
MSR R17, DBGBCR9_EL1 // b10910d5
|
||||||
|
MSR R22, DBGBCR10_EL1 // b60a10d5
|
||||||
|
MSR R16, DBGBCR11_EL1 // b00b10d5
|
||||||
|
MSR R24, DBGBCR12_EL1 // b80c10d5
|
||||||
|
MSR R29, DBGBCR13_EL1 // bd0d10d5
|
||||||
|
MSR R1, DBGBCR14_EL1 // a10e10d5
|
||||||
|
MSR R10, DBGBCR15_EL1 // aa0f10d5
|
||||||
|
MRS DBGBVR0_EL1, R16 // 900030d5
|
||||||
|
MRS DBGBVR1_EL1, R21 // 950130d5
|
||||||
|
MRS DBGBVR2_EL1, R13 // 8d0230d5
|
||||||
|
MRS DBGBVR3_EL1, R12 // 8c0330d5
|
||||||
|
MRS DBGBVR4_EL1, R20 // 940430d5
|
||||||
|
MRS DBGBVR5_EL1, R21 // 950530d5
|
||||||
|
MRS DBGBVR6_EL1, R27 // 9b0630d5
|
||||||
|
MRS DBGBVR7_EL1, R6 // 860730d5
|
||||||
|
MRS DBGBVR8_EL1, R14 // 8e0830d5
|
||||||
|
MRS DBGBVR9_EL1, R5 // 850930d5
|
||||||
|
MRS DBGBVR10_EL1, R9 // 890a30d5
|
||||||
|
MRS DBGBVR11_EL1, R25 // 990b30d5
|
||||||
|
MRS DBGBVR12_EL1, R30 // 9e0c30d5
|
||||||
|
MRS DBGBVR13_EL1, R1 // 810d30d5
|
||||||
|
MRS DBGBVR14_EL1, R17 // 910e30d5
|
||||||
|
MRS DBGBVR15_EL1, R25 // 990f30d5
|
||||||
|
MSR R15, DBGBVR0_EL1 // 8f0010d5
|
||||||
|
MSR R6, DBGBVR1_EL1 // 860110d5
|
||||||
|
MSR R24, DBGBVR2_EL1 // 980210d5
|
||||||
|
MSR R17, DBGBVR3_EL1 // 910310d5
|
||||||
|
MSR R3, DBGBVR4_EL1 // 830410d5
|
||||||
|
MSR R21, DBGBVR5_EL1 // 950510d5
|
||||||
|
MSR R5, DBGBVR6_EL1 // 850610d5
|
||||||
|
MSR R6, DBGBVR7_EL1 // 860710d5
|
||||||
|
MSR R25, DBGBVR8_EL1 // 990810d5
|
||||||
|
MSR R4, DBGBVR9_EL1 // 840910d5
|
||||||
|
MSR R25, DBGBVR10_EL1 // 990a10d5
|
||||||
|
MSR R17, DBGBVR11_EL1 // 910b10d5
|
||||||
|
MSR R0, DBGBVR12_EL1 // 800c10d5
|
||||||
|
MSR R5, DBGBVR13_EL1 // 850d10d5
|
||||||
|
MSR R9, DBGBVR14_EL1 // 890e10d5
|
||||||
|
MSR R12, DBGBVR15_EL1 // 8c0f10d5
|
||||||
|
MRS DBGCLAIMCLR_EL1, R27 // db7930d5
|
||||||
|
MSR R0, DBGCLAIMCLR_EL1 // c07910d5
|
||||||
|
MRS DBGCLAIMSET_EL1, R7 // c77830d5
|
||||||
|
MSR R13, DBGCLAIMSET_EL1 // cd7810d5
|
||||||
|
MRS DBGDTRRX_EL0, R0 // 000533d5
|
||||||
|
MSR R29, DBGDTRTX_EL0 // 1d0513d5
|
||||||
|
MRS DBGDTR_EL0, R27 // 1b0433d5
|
||||||
|
MSR R30, DBGDTR_EL0 // 1e0413d5
|
||||||
|
MRS DBGPRCR_EL1, R4 // 841430d5
|
||||||
|
MSR R0, DBGPRCR_EL1 // 801410d5
|
||||||
|
MRS DBGWCR0_EL1, R24 // f80030d5
|
||||||
|
MRS DBGWCR1_EL1, R19 // f30130d5
|
||||||
|
MRS DBGWCR2_EL1, R25 // f90230d5
|
||||||
|
MRS DBGWCR3_EL1, R0 // e00330d5
|
||||||
|
MRS DBGWCR4_EL1, R13 // ed0430d5
|
||||||
|
MRS DBGWCR5_EL1, R8 // e80530d5
|
||||||
|
MRS DBGWCR6_EL1, R22 // f60630d5
|
||||||
|
MRS DBGWCR7_EL1, R11 // eb0730d5
|
||||||
|
MRS DBGWCR8_EL1, R11 // eb0830d5
|
||||||
|
MRS DBGWCR9_EL1, R3 // e30930d5
|
||||||
|
MRS DBGWCR10_EL1, R17 // f10a30d5
|
||||||
|
MRS DBGWCR11_EL1, R21 // f50b30d5
|
||||||
|
MRS DBGWCR12_EL1, R10 // ea0c30d5
|
||||||
|
MRS DBGWCR13_EL1, R22 // f60d30d5
|
||||||
|
MRS DBGWCR14_EL1, R11 // eb0e30d5
|
||||||
|
MRS DBGWCR15_EL1, R0 // e00f30d5
|
||||||
|
MSR R24, DBGWCR0_EL1 // f80010d5
|
||||||
|
MSR R8, DBGWCR1_EL1 // e80110d5
|
||||||
|
MSR R17, DBGWCR2_EL1 // f10210d5
|
||||||
|
MSR R29, DBGWCR3_EL1 // fd0310d5
|
||||||
|
MSR R13, DBGWCR4_EL1 // ed0410d5
|
||||||
|
MSR R22, DBGWCR5_EL1 // f60510d5
|
||||||
|
MSR R3, DBGWCR6_EL1 // e30610d5
|
||||||
|
MSR R4, DBGWCR7_EL1 // e40710d5
|
||||||
|
MSR R7, DBGWCR8_EL1 // e70810d5
|
||||||
|
MSR R29, DBGWCR9_EL1 // fd0910d5
|
||||||
|
MSR R3, DBGWCR10_EL1 // e30a10d5
|
||||||
|
MSR R11, DBGWCR11_EL1 // eb0b10d5
|
||||||
|
MSR R20, DBGWCR12_EL1 // f40c10d5
|
||||||
|
MSR R6, DBGWCR13_EL1 // e60d10d5
|
||||||
|
MSR R22, DBGWCR14_EL1 // f60e10d5
|
||||||
|
MSR R25, DBGWCR15_EL1 // f90f10d5
|
||||||
|
MRS DBGWVR0_EL1, R14 // ce0030d5
|
||||||
|
MRS DBGWVR1_EL1, R16 // d00130d5
|
||||||
|
MRS DBGWVR2_EL1, R15 // cf0230d5
|
||||||
|
MRS DBGWVR3_EL1, R1 // c10330d5
|
||||||
|
MRS DBGWVR4_EL1, R26 // da0430d5
|
||||||
|
MRS DBGWVR5_EL1, R14 // ce0530d5
|
||||||
|
MRS DBGWVR6_EL1, R17 // d10630d5
|
||||||
|
MRS DBGWVR7_EL1, R22 // d60730d5
|
||||||
|
MRS DBGWVR8_EL1, R4 // c40830d5
|
||||||
|
MRS DBGWVR9_EL1, R3 // c30930d5
|
||||||
|
MRS DBGWVR10_EL1, R16 // d00a30d5
|
||||||
|
MRS DBGWVR11_EL1, R2 // c20b30d5
|
||||||
|
MRS DBGWVR12_EL1, R5 // c50c30d5
|
||||||
|
MRS DBGWVR13_EL1, R23 // d70d30d5
|
||||||
|
MRS DBGWVR14_EL1, R5 // c50e30d5
|
||||||
|
MRS DBGWVR15_EL1, R6 // c60f30d5
|
||||||
|
MSR R24, DBGWVR0_EL1 // d80010d5
|
||||||
|
MSR R6, DBGWVR1_EL1 // c60110d5
|
||||||
|
MSR R1, DBGWVR2_EL1 // c10210d5
|
||||||
|
MSR R24, DBGWVR3_EL1 // d80310d5
|
||||||
|
MSR R24, DBGWVR4_EL1 // d80410d5
|
||||||
|
MSR R0, DBGWVR5_EL1 // c00510d5
|
||||||
|
MSR R10, DBGWVR6_EL1 // ca0610d5
|
||||||
|
MSR R17, DBGWVR7_EL1 // d10710d5
|
||||||
|
MSR R7, DBGWVR8_EL1 // c70810d5
|
||||||
|
MSR R8, DBGWVR9_EL1 // c80910d5
|
||||||
|
MSR R15, DBGWVR10_EL1 // cf0a10d5
|
||||||
|
MSR R8, DBGWVR11_EL1 // c80b10d5
|
||||||
|
MSR R7, DBGWVR12_EL1 // c70c10d5
|
||||||
|
MSR R14, DBGWVR13_EL1 // ce0d10d5
|
||||||
|
MSR R16, DBGWVR14_EL1 // d00e10d5
|
||||||
|
MSR R5, DBGWVR15_EL1 // c50f10d5
|
||||||
|
MRS DCZID_EL0, R21 // f5003bd5
|
||||||
|
MRS DISR_EL1, R8 // 28c138d5
|
||||||
|
MSR R5, DISR_EL1 // 25c118d5
|
||||||
|
MRS DIT, R29 // bd423bd5
|
||||||
|
MSR R22, DIT // b6421bd5
|
||||||
|
MRS DLR_EL0, R25 // 39453bd5
|
||||||
|
MSR R9, DLR_EL0 // 29451bd5
|
||||||
|
MRS DSPSR_EL0, R3 // 03453bd5
|
||||||
|
MSR R10, DSPSR_EL0 // 0a451bd5
|
||||||
|
MRS ELR_EL1, R24 // 384038d5
|
||||||
|
MSR R3, ELR_EL1 // 234018d5
|
||||||
|
MRS ELR_EL1, R13 // 2d4038d5
|
||||||
|
MSR R27, ELR_EL1 // 3b4018d5
|
||||||
|
MRS ERRIDR_EL1, R30 // 1e5338d5
|
||||||
|
MRS ERRSELR_EL1, R21 // 355338d5
|
||||||
|
MSR R22, ERRSELR_EL1 // 365318d5
|
||||||
|
MRS ERXADDR_EL1, R30 // 7e5438d5
|
||||||
|
MSR R0, ERXADDR_EL1 // 605418d5
|
||||||
|
MRS ERXCTLR_EL1, R6 // 265438d5
|
||||||
|
MSR R9, ERXCTLR_EL1 // 295418d5
|
||||||
|
MRS ERXFR_EL1, R19 // 135438d5
|
||||||
|
MRS ERXMISC0_EL1, R20 // 145538d5
|
||||||
|
MSR R24, ERXMISC0_EL1 // 185518d5
|
||||||
|
MRS ERXMISC1_EL1, R15 // 2f5538d5
|
||||||
|
MSR R10, ERXMISC1_EL1 // 2a5518d5
|
||||||
|
MRS ERXSTATUS_EL1, R30 // 5e5438d5
|
||||||
|
MSR R3, ERXSTATUS_EL1 // 435418d5
|
||||||
|
MRS ESR_EL1, R6 // 065238d5
|
||||||
|
MSR R21, ESR_EL1 // 155218d5
|
||||||
|
MRS ESR_EL1, R17 // 115238d5
|
||||||
|
MSR R12, ESR_EL1 // 0c5218d5
|
||||||
|
MRS FAR_EL1, R3 // 036038d5
|
||||||
|
MSR R17, FAR_EL1 // 116018d5
|
||||||
|
MRS FAR_EL1, R9 // 096038d5
|
||||||
|
MSR R25, FAR_EL1 // 196018d5
|
||||||
|
MRS FPCR, R1 // 01443bd5
|
||||||
|
MSR R27, FPCR // 1b441bd5
|
||||||
|
MRS FPSR, R5 // 25443bd5
|
||||||
|
MSR R15, FPSR // 2f441bd5
|
||||||
|
MRS ID_AA64AFR0_EL1, R19 // 930538d5
|
||||||
|
MRS ID_AA64AFR1_EL1, R24 // b80538d5
|
||||||
|
MRS ID_AA64DFR0_EL1, R21 // 150538d5
|
||||||
|
MRS ID_AA64DFR1_EL1, R20 // 340538d5
|
||||||
|
MRS ID_AA64ISAR0_EL1, R4 // 040638d5
|
||||||
|
MRS ID_AA64ISAR1_EL1, R6 // 260638d5
|
||||||
|
MRS ID_AA64MMFR0_EL1, R0 // 000738d5
|
||||||
|
MRS ID_AA64MMFR1_EL1, R17 // 310738d5
|
||||||
|
MRS ID_AA64MMFR2_EL1, R23 // 570738d5
|
||||||
|
MRS ID_AA64PFR0_EL1, R20 // 140438d5
|
||||||
|
MRS ID_AA64PFR1_EL1, R26 // 3a0438d5
|
||||||
|
MRS ID_AA64ZFR0_EL1, R26 // 9a0438d5
|
||||||
|
MRS ID_AFR0_EL1, R21 // 750138d5
|
||||||
|
MRS ID_DFR0_EL1, R15 // 4f0138d5
|
||||||
|
MRS ID_ISAR0_EL1, R11 // 0b0238d5
|
||||||
|
MRS ID_ISAR1_EL1, R16 // 300238d5
|
||||||
|
MRS ID_ISAR2_EL1, R10 // 4a0238d5
|
||||||
|
MRS ID_ISAR3_EL1, R13 // 6d0238d5
|
||||||
|
MRS ID_ISAR4_EL1, R24 // 980238d5
|
||||||
|
MRS ID_ISAR5_EL1, R29 // bd0238d5
|
||||||
|
MRS ID_MMFR0_EL1, R10 // 8a0138d5
|
||||||
|
MRS ID_MMFR1_EL1, R29 // bd0138d5
|
||||||
|
MRS ID_MMFR2_EL1, R16 // d00138d5
|
||||||
|
MRS ID_MMFR3_EL1, R10 // ea0138d5
|
||||||
|
MRS ID_MMFR4_EL1, R23 // d70238d5
|
||||||
|
MRS ID_PFR0_EL1, R4 // 040138d5
|
||||||
|
MRS ID_PFR1_EL1, R12 // 2c0138d5
|
||||||
|
MRS ISR_EL1, R24 // 18c138d5
|
||||||
|
MRS MAIR_EL1, R20 // 14a238d5
|
||||||
|
MSR R21, MAIR_EL1 // 15a218d5
|
||||||
|
MRS MAIR_EL1, R20 // 14a238d5
|
||||||
|
MSR R5, MAIR_EL1 // 05a218d5
|
||||||
|
MRS MDCCINT_EL1, R23 // 170230d5
|
||||||
|
MSR R27, MDCCINT_EL1 // 1b0210d5
|
||||||
|
MRS MDCCSR_EL0, R19 // 130133d5
|
||||||
|
MRS MDRAR_EL1, R12 // 0c1030d5
|
||||||
|
MRS MDSCR_EL1, R15 // 4f0230d5
|
||||||
|
MSR R15, MDSCR_EL1 // 4f0210d5
|
||||||
|
MRS MIDR_EL1, R26 // 1a0038d5
|
||||||
|
MRS MPIDR_EL1, R25 // b90038d5
|
||||||
|
MRS MVFR0_EL1, R29 // 1d0338d5
|
||||||
|
MRS MVFR1_EL1, R7 // 270338d5
|
||||||
|
MRS MVFR2_EL1, R19 // 530338d5
|
||||||
|
MRS NZCV, R11 // 0b423bd5
|
||||||
|
MSR R10, NZCV // 0a421bd5
|
||||||
|
MRS OSDLR_EL1, R16 // 901330d5
|
||||||
|
MSR R21, OSDLR_EL1 // 951310d5
|
||||||
|
MRS OSDTRRX_EL1, R5 // 450030d5
|
||||||
|
MSR R30, OSDTRRX_EL1 // 5e0010d5
|
||||||
|
MRS OSDTRTX_EL1, R3 // 430330d5
|
||||||
|
MSR R13, OSDTRTX_EL1 // 4d0310d5
|
||||||
|
MRS OSECCR_EL1, R2 // 420630d5
|
||||||
|
MSR R17, OSECCR_EL1 // 510610d5
|
||||||
|
MSR R3, OSLAR_EL1 // 831010d5
|
||||||
|
MRS OSLSR_EL1, R15 // 8f1130d5
|
||||||
|
MRS PAN, R14 // 6e4238d5
|
||||||
|
MSR R0, PAN // 604218d5
|
||||||
|
MRS PAR_EL1, R27 // 1b7438d5
|
||||||
|
MSR R3, PAR_EL1 // 037418d5
|
||||||
|
MRS PMCCFILTR_EL0, R10 // eaef3bd5
|
||||||
|
MSR R16, PMCCFILTR_EL0 // f0ef1bd5
|
||||||
|
MRS PMCCNTR_EL0, R17 // 119d3bd5
|
||||||
|
MSR R13, PMCCNTR_EL0 // 0d9d1bd5
|
||||||
|
MRS PMCEID0_EL0, R8 // c89c3bd5
|
||||||
|
MRS PMCEID1_EL0, R30 // fe9c3bd5
|
||||||
|
MRS PMCNTENCLR_EL0, R11 // 4b9c3bd5
|
||||||
|
MSR R21, PMCNTENCLR_EL0 // 559c1bd5
|
||||||
|
MRS PMCNTENSET_EL0, R25 // 399c3bd5
|
||||||
|
MSR R13, PMCNTENSET_EL0 // 2d9c1bd5
|
||||||
|
MRS PMCR_EL0, R23 // 179c3bd5
|
||||||
|
MSR R11, PMCR_EL0 // 0b9c1bd5
|
||||||
|
MRS PMEVCNTR0_EL0, R27 // 1be83bd5
|
||||||
|
MRS PMEVCNTR1_EL0, R23 // 37e83bd5
|
||||||
|
MRS PMEVCNTR2_EL0, R26 // 5ae83bd5
|
||||||
|
MRS PMEVCNTR3_EL0, R11 // 6be83bd5
|
||||||
|
MRS PMEVCNTR4_EL0, R14 // 8ee83bd5
|
||||||
|
MRS PMEVCNTR5_EL0, R9 // a9e83bd5
|
||||||
|
MRS PMEVCNTR6_EL0, R30 // dee83bd5
|
||||||
|
MRS PMEVCNTR7_EL0, R19 // f3e83bd5
|
||||||
|
MRS PMEVCNTR8_EL0, R5 // 05e93bd5
|
||||||
|
MRS PMEVCNTR9_EL0, R27 // 3be93bd5
|
||||||
|
MRS PMEVCNTR10_EL0, R23 // 57e93bd5
|
||||||
|
MRS PMEVCNTR11_EL0, R27 // 7be93bd5
|
||||||
|
MRS PMEVCNTR12_EL0, R0 // 80e93bd5
|
||||||
|
MRS PMEVCNTR13_EL0, R13 // ade93bd5
|
||||||
|
MRS PMEVCNTR14_EL0, R27 // dbe93bd5
|
||||||
|
MRS PMEVCNTR15_EL0, R16 // f0e93bd5
|
||||||
|
MRS PMEVCNTR16_EL0, R16 // 10ea3bd5
|
||||||
|
MRS PMEVCNTR17_EL0, R14 // 2eea3bd5
|
||||||
|
MRS PMEVCNTR18_EL0, R10 // 4aea3bd5
|
||||||
|
MRS PMEVCNTR19_EL0, R12 // 6cea3bd5
|
||||||
|
MRS PMEVCNTR20_EL0, R5 // 85ea3bd5
|
||||||
|
MRS PMEVCNTR21_EL0, R26 // baea3bd5
|
||||||
|
MRS PMEVCNTR22_EL0, R19 // d3ea3bd5
|
||||||
|
MRS PMEVCNTR23_EL0, R5 // e5ea3bd5
|
||||||
|
MRS PMEVCNTR24_EL0, R17 // 11eb3bd5
|
||||||
|
MRS PMEVCNTR25_EL0, R0 // 20eb3bd5
|
||||||
|
MRS PMEVCNTR26_EL0, R20 // 54eb3bd5
|
||||||
|
MRS PMEVCNTR27_EL0, R12 // 6ceb3bd5
|
||||||
|
MRS PMEVCNTR28_EL0, R29 // 9deb3bd5
|
||||||
|
MRS PMEVCNTR29_EL0, R22 // b6eb3bd5
|
||||||
|
MRS PMEVCNTR30_EL0, R22 // d6eb3bd5
|
||||||
|
MSR R30, PMEVCNTR0_EL0 // 1ee81bd5
|
||||||
|
MSR R1, PMEVCNTR1_EL0 // 21e81bd5
|
||||||
|
MSR R20, PMEVCNTR2_EL0 // 54e81bd5
|
||||||
|
MSR R9, PMEVCNTR3_EL0 // 69e81bd5
|
||||||
|
MSR R8, PMEVCNTR4_EL0 // 88e81bd5
|
||||||
|
MSR R2, PMEVCNTR5_EL0 // a2e81bd5
|
||||||
|
MSR R30, PMEVCNTR6_EL0 // dee81bd5
|
||||||
|
MSR R14, PMEVCNTR7_EL0 // eee81bd5
|
||||||
|
MSR R1, PMEVCNTR8_EL0 // 01e91bd5
|
||||||
|
MSR R15, PMEVCNTR9_EL0 // 2fe91bd5
|
||||||
|
MSR R15, PMEVCNTR10_EL0 // 4fe91bd5
|
||||||
|
MSR R14, PMEVCNTR11_EL0 // 6ee91bd5
|
||||||
|
MSR R15, PMEVCNTR12_EL0 // 8fe91bd5
|
||||||
|
MSR R25, PMEVCNTR13_EL0 // b9e91bd5
|
||||||
|
MSR R26, PMEVCNTR14_EL0 // dae91bd5
|
||||||
|
MSR R21, PMEVCNTR15_EL0 // f5e91bd5
|
||||||
|
MSR R29, PMEVCNTR16_EL0 // 1dea1bd5
|
||||||
|
MSR R11, PMEVCNTR17_EL0 // 2bea1bd5
|
||||||
|
MSR R16, PMEVCNTR18_EL0 // 50ea1bd5
|
||||||
|
MSR R2, PMEVCNTR19_EL0 // 62ea1bd5
|
||||||
|
MSR R19, PMEVCNTR20_EL0 // 93ea1bd5
|
||||||
|
MSR R17, PMEVCNTR21_EL0 // b1ea1bd5
|
||||||
|
MSR R7, PMEVCNTR22_EL0 // c7ea1bd5
|
||||||
|
MSR R23, PMEVCNTR23_EL0 // f7ea1bd5
|
||||||
|
MSR R15, PMEVCNTR24_EL0 // 0feb1bd5
|
||||||
|
MSR R27, PMEVCNTR25_EL0 // 3beb1bd5
|
||||||
|
MSR R13, PMEVCNTR26_EL0 // 4deb1bd5
|
||||||
|
MSR R2, PMEVCNTR27_EL0 // 62eb1bd5
|
||||||
|
MSR R15, PMEVCNTR28_EL0 // 8feb1bd5
|
||||||
|
MSR R14, PMEVCNTR29_EL0 // aeeb1bd5
|
||||||
|
MSR R23, PMEVCNTR30_EL0 // d7eb1bd5
|
||||||
|
MRS PMEVTYPER0_EL0, R23 // 17ec3bd5
|
||||||
|
MRS PMEVTYPER1_EL0, R30 // 3eec3bd5
|
||||||
|
MRS PMEVTYPER2_EL0, R12 // 4cec3bd5
|
||||||
|
MRS PMEVTYPER3_EL0, R13 // 6dec3bd5
|
||||||
|
MRS PMEVTYPER4_EL0, R25 // 99ec3bd5
|
||||||
|
MRS PMEVTYPER5_EL0, R23 // b7ec3bd5
|
||||||
|
MRS PMEVTYPER6_EL0, R8 // c8ec3bd5
|
||||||
|
MRS PMEVTYPER7_EL0, R2 // e2ec3bd5
|
||||||
|
MRS PMEVTYPER8_EL0, R23 // 17ed3bd5
|
||||||
|
MRS PMEVTYPER9_EL0, R25 // 39ed3bd5
|
||||||
|
MRS PMEVTYPER10_EL0, R0 // 40ed3bd5
|
||||||
|
MRS PMEVTYPER11_EL0, R30 // 7eed3bd5
|
||||||
|
MRS PMEVTYPER12_EL0, R0 // 80ed3bd5
|
||||||
|
MRS PMEVTYPER13_EL0, R9 // a9ed3bd5
|
||||||
|
MRS PMEVTYPER14_EL0, R15 // cfed3bd5
|
||||||
|
MRS PMEVTYPER15_EL0, R13 // eded3bd5
|
||||||
|
MRS PMEVTYPER16_EL0, R11 // 0bee3bd5
|
||||||
|
MRS PMEVTYPER17_EL0, R19 // 33ee3bd5
|
||||||
|
MRS PMEVTYPER18_EL0, R3 // 43ee3bd5
|
||||||
|
MRS PMEVTYPER19_EL0, R17 // 71ee3bd5
|
||||||
|
MRS PMEVTYPER20_EL0, R8 // 88ee3bd5
|
||||||
|
MRS PMEVTYPER21_EL0, R2 // a2ee3bd5
|
||||||
|
MRS PMEVTYPER22_EL0, R5 // c5ee3bd5
|
||||||
|
MRS PMEVTYPER23_EL0, R17 // f1ee3bd5
|
||||||
|
MRS PMEVTYPER24_EL0, R22 // 16ef3bd5
|
||||||
|
MRS PMEVTYPER25_EL0, R3 // 23ef3bd5
|
||||||
|
MRS PMEVTYPER26_EL0, R23 // 57ef3bd5
|
||||||
|
MRS PMEVTYPER27_EL0, R19 // 73ef3bd5
|
||||||
|
MRS PMEVTYPER28_EL0, R24 // 98ef3bd5
|
||||||
|
MRS PMEVTYPER29_EL0, R3 // a3ef3bd5
|
||||||
|
MRS PMEVTYPER30_EL0, R1 // c1ef3bd5
|
||||||
|
MSR R20, PMEVTYPER0_EL0 // 14ec1bd5
|
||||||
|
MSR R20, PMEVTYPER1_EL0 // 34ec1bd5
|
||||||
|
MSR R14, PMEVTYPER2_EL0 // 4eec1bd5
|
||||||
|
MSR R26, PMEVTYPER3_EL0 // 7aec1bd5
|
||||||
|
MSR R11, PMEVTYPER4_EL0 // 8bec1bd5
|
||||||
|
MSR R16, PMEVTYPER5_EL0 // b0ec1bd5
|
||||||
|
MSR R29, PMEVTYPER6_EL0 // ddec1bd5
|
||||||
|
MSR R3, PMEVTYPER7_EL0 // e3ec1bd5
|
||||||
|
MSR R30, PMEVTYPER8_EL0 // 1eed1bd5
|
||||||
|
MSR R17, PMEVTYPER9_EL0 // 31ed1bd5
|
||||||
|
MSR R10, PMEVTYPER10_EL0 // 4aed1bd5
|
||||||
|
MSR R19, PMEVTYPER11_EL0 // 73ed1bd5
|
||||||
|
MSR R13, PMEVTYPER12_EL0 // 8ded1bd5
|
||||||
|
MSR R23, PMEVTYPER13_EL0 // b7ed1bd5
|
||||||
|
MSR R13, PMEVTYPER14_EL0 // cded1bd5
|
||||||
|
MSR R9, PMEVTYPER15_EL0 // e9ed1bd5
|
||||||
|
MSR R1, PMEVTYPER16_EL0 // 01ee1bd5
|
||||||
|
MSR R19, PMEVTYPER17_EL0 // 33ee1bd5
|
||||||
|
MSR R22, PMEVTYPER18_EL0 // 56ee1bd5
|
||||||
|
MSR R23, PMEVTYPER19_EL0 // 77ee1bd5
|
||||||
|
MSR R30, PMEVTYPER20_EL0 // 9eee1bd5
|
||||||
|
MSR R9, PMEVTYPER21_EL0 // a9ee1bd5
|
||||||
|
MSR R3, PMEVTYPER22_EL0 // c3ee1bd5
|
||||||
|
MSR R1, PMEVTYPER23_EL0 // e1ee1bd5
|
||||||
|
MSR R16, PMEVTYPER24_EL0 // 10ef1bd5
|
||||||
|
MSR R12, PMEVTYPER25_EL0 // 2cef1bd5
|
||||||
|
MSR R7, PMEVTYPER26_EL0 // 47ef1bd5
|
||||||
|
MSR R9, PMEVTYPER27_EL0 // 69ef1bd5
|
||||||
|
MSR R10, PMEVTYPER28_EL0 // 8aef1bd5
|
||||||
|
MSR R5, PMEVTYPER29_EL0 // a5ef1bd5
|
||||||
|
MSR R12, PMEVTYPER30_EL0 // ccef1bd5
|
||||||
|
MRS PMINTENCLR_EL1, R24 // 589e38d5
|
||||||
|
MSR R15, PMINTENCLR_EL1 // 4f9e18d5
|
||||||
|
MRS PMINTENSET_EL1, R1 // 219e38d5
|
||||||
|
MSR R4, PMINTENSET_EL1 // 249e18d5
|
||||||
|
MRS PMOVSCLR_EL0, R6 // 669c3bd5
|
||||||
|
MSR R30, PMOVSCLR_EL0 // 7e9c1bd5
|
||||||
|
MRS PMOVSSET_EL0, R16 // 709e3bd5
|
||||||
|
MSR R12, PMOVSSET_EL0 // 6c9e1bd5
|
||||||
|
MRS PMSELR_EL0, R30 // be9c3bd5
|
||||||
|
MSR R5, PMSELR_EL0 // a59c1bd5
|
||||||
|
MSR R27, PMSWINC_EL0 // 9b9c1bd5
|
||||||
|
MRS PMUSERENR_EL0, R8 // 089e3bd5
|
||||||
|
MSR R6, PMUSERENR_EL0 // 069e1bd5
|
||||||
|
MRS PMXEVCNTR_EL0, R26 // 5a9d3bd5
|
||||||
|
MSR R10, PMXEVCNTR_EL0 // 4a9d1bd5
|
||||||
|
MRS PMXEVTYPER_EL0, R4 // 249d3bd5
|
||||||
|
MSR R4, PMXEVTYPER_EL0 // 249d1bd5
|
||||||
|
MRS REVIDR_EL1, R29 // dd0038d5
|
||||||
|
MRS RMR_EL1, R4 // 44c038d5
|
||||||
|
MSR R0, RMR_EL1 // 40c018d5
|
||||||
|
MRS RVBAR_EL1, R7 // 27c038d5
|
||||||
|
MRS SCTLR_EL1, R8 // 081038d5
|
||||||
|
MSR R0, SCTLR_EL1 // 001018d5
|
||||||
|
MRS SCTLR_EL1, R30 // 1e1038d5
|
||||||
|
MSR R13, SCTLR_EL1 // 0d1018d5
|
||||||
|
MRS SPSR_EL1, R1 // 014038d5
|
||||||
|
MSR R2, SPSR_EL1 // 024018d5
|
||||||
|
MRS SPSR_EL1, R3 // 034038d5
|
||||||
|
MSR R14, SPSR_EL1 // 0e4018d5
|
||||||
|
MRS SPSR_abt, R12 // 2c433cd5
|
||||||
|
MSR R4, SPSR_abt // 24431cd5
|
||||||
|
MRS SPSR_fiq, R17 // 71433cd5
|
||||||
|
MSR R9, SPSR_fiq // 69431cd5
|
||||||
|
MRS SPSR_irq, R12 // 0c433cd5
|
||||||
|
MSR R23, SPSR_irq // 17431cd5
|
||||||
|
MRS SPSR_und, R29 // 5d433cd5
|
||||||
|
MSR R3, SPSR_und // 43431cd5
|
||||||
|
MRS SPSel, R29 // 1d4238d5
|
||||||
|
MSR R1, SPSel // 014218d5
|
||||||
|
MRS SP_EL0, R10 // 0a4138d5
|
||||||
|
MSR R4, SP_EL0 // 044118d5
|
||||||
|
MRS SP_EL1, R22 // 16413cd5
|
||||||
|
MSR R17, SP_EL1 // 11411cd5
|
||||||
|
MRS TCR_EL1, R17 // 512038d5
|
||||||
|
MSR R23, TCR_EL1 // 572018d5
|
||||||
|
MRS TCR_EL1, R14 // 4e2038d5
|
||||||
|
MSR R29, TCR_EL1 // 5d2018d5
|
||||||
|
MRS TPIDRRO_EL0, R26 // 7ad03bd5
|
||||||
|
MSR R16, TPIDRRO_EL0 // 70d01bd5
|
||||||
|
MRS TPIDR_EL0, R23 // 57d03bd5
|
||||||
|
MSR R5, TPIDR_EL0 // 45d01bd5
|
||||||
|
MRS TPIDR_EL1, R17 // 91d038d5
|
||||||
|
MSR R22, TPIDR_EL1 // 96d018d5
|
||||||
|
MRS TTBR0_EL1, R30 // 1e2038d5
|
||||||
|
MSR R29, TTBR0_EL1 // 1d2018d5
|
||||||
|
MRS TTBR0_EL1, R23 // 172038d5
|
||||||
|
MSR R15, TTBR0_EL1 // 0f2018d5
|
||||||
|
MRS TTBR1_EL1, R5 // 252038d5
|
||||||
|
MSR R26, TTBR1_EL1 // 3a2018d5
|
||||||
|
MRS TTBR1_EL1, R19 // 332038d5
|
||||||
|
MSR R23, TTBR1_EL1 // 372018d5
|
||||||
|
MRS UAO, R22 // 964238d5
|
||||||
|
MSR R4, UAO // 844218d5
|
||||||
|
MRS VBAR_EL1, R23 // 17c038d5
|
||||||
|
MSR R2, VBAR_EL1 // 02c018d5
|
||||||
|
MRS VBAR_EL1, R6 // 06c038d5
|
||||||
|
MSR R3, VBAR_EL1 // 03c018d5
|
||||||
|
MRS DISR_EL1, R12 // 2cc138d5
|
||||||
|
MSR R24, DISR_EL1 // 38c118d5
|
||||||
|
MRS MPIDR_EL1, R1 // a10038d5
|
||||||
|
MRS MIDR_EL1, R13 // 0d0038d5
|
||||||
|
MRS ZCR_EL1, R24 // 181238d5
|
||||||
|
MSR R13, ZCR_EL1 // 0d1218d5
|
||||||
|
MRS ZCR_EL1, R23 // 171238d5
|
||||||
|
MSR R17, ZCR_EL1 // 111218d5
|
||||||
|
|
||||||
// END
|
// END
|
||||||
//
|
//
|
||||||
|
|
|
||||||
3
src/cmd/asm/internal/asm/testdata/arm64enc.s
vendored
3
src/cmd/asm/internal/asm/testdata/arm64enc.s
vendored
|
|
@ -152,6 +152,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$-8
|
||||||
EXTR $35, R22, R12, R8 // 888dd693
|
EXTR $35, R22, R12, R8 // 888dd693
|
||||||
SEVL // bf2003d5
|
SEVL // bf2003d5
|
||||||
HINT $6 // df2003d5
|
HINT $6 // df2003d5
|
||||||
|
HINT $0 // 1f2003d5
|
||||||
HLT $65509 // a0fc5fd4
|
HLT $65509 // a0fc5fd4
|
||||||
HVC $61428 // 82fe1dd4
|
HVC $61428 // 82fe1dd4
|
||||||
ISB $1 // df3103d5
|
ISB $1 // df3103d5
|
||||||
|
|
@ -281,7 +282,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$-8
|
||||||
NGC R2, R7 // e70302da
|
NGC R2, R7 // e70302da
|
||||||
NGCSW R10, R5 // e5030a7a
|
NGCSW R10, R5 // e5030a7a
|
||||||
NGCS R24, R16 // f00318fa
|
NGCS R24, R16 // f00318fa
|
||||||
//TODO NOP // 1f2003d5
|
NOOP // 1f2003d5
|
||||||
ORNW R4@>11, R16, R3 // 032ee42a
|
ORNW R4@>11, R16, R3 // 032ee42a
|
||||||
ORN R22@>19, R3, R3 // 634cf6aa
|
ORN R22@>19, R3, R3 // 634cf6aa
|
||||||
ORRW $4294443071, R15, R24 // f8490d32
|
ORRW $4294443071, R15, R24 // f8490d32
|
||||||
|
|
|
||||||
104
src/cmd/asm/internal/asm/testdata/arm64error.s
vendored
104
src/cmd/asm/internal/asm/testdata/arm64error.s
vendored
|
|
@ -232,4 +232,108 @@ TEXT errors(SB),$0
|
||||||
STXPW (R5, R7), (R6), RSP // ERROR "illegal destination register"
|
STXPW (R5, R7), (R6), RSP // ERROR "illegal destination register"
|
||||||
STLXP (R5, R7), (R6), RSP // ERROR "illegal destination register"
|
STLXP (R5, R7), (R6), RSP // ERROR "illegal destination register"
|
||||||
STLXP (R5, R7), (R6), RSP // ERROR "illegal destination register"
|
STLXP (R5, R7), (R6), RSP // ERROR "illegal destination register"
|
||||||
|
MSR OSLAR_EL1, R5 // ERROR "illegal combination"
|
||||||
|
MRS R11, AIDR_EL1 // ERROR "illegal combination"
|
||||||
|
MSR R6, AIDR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMCFGR_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMCGCR_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMEVTYPER00_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMEVTYPER01_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMEVTYPER02_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMEVTYPER03_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMEVTYPER04_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMEVTYPER05_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMEVTYPER06_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMEVTYPER07_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMEVTYPER08_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMEVTYPER09_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMEVTYPER010_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMEVTYPER011_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMEVTYPER012_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMEVTYPER013_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMEVTYPER014_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, AMEVTYPER015_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, CCSIDR2_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, CCSIDR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, CLIDR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, CNTPCT_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, CNTVCT_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, CTR_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, CurrentEL // ERROR "system register is not writable"
|
||||||
|
MSR R6, DBGAUTHSTATUS_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, DBGDTRRX_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, DCZID_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ERRIDR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ERXFR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ERXPFGF_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, GMID_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ICC_HPPIR0_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ICC_HPPIR1_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ICC_IAR0_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ICC_IAR1_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ICC_RPR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ICV_HPPIR0_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ICV_HPPIR1_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ICV_IAR0_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ICV_IAR1_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ICV_RPR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_AA64AFR0_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_AA64AFR1_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_AA64DFR0_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_AA64DFR1_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_AA64ISAR0_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_AA64ISAR1_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_AA64MMFR0_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_AA64MMFR1_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_AA64MMFR2_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_AA64PFR0_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_AA64PFR1_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_AA64ZFR0_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_AFR0_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_DFR0_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_ISAR0_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_ISAR1_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_ISAR2_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_ISAR3_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_ISAR4_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_ISAR5_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_ISAR6_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_MMFR0_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_MMFR1_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_MMFR2_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_MMFR3_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_MMFR4_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_PFR0_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_PFR1_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ID_PFR2_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, ISR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, LORID_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, MDCCSR_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, MDRAR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, MIDR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, MPAMIDR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, MPIDR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, MVFR0_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, MVFR1_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, MVFR2_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, OSLSR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, PMBIDR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, PMCEID0_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, PMCEID1_EL0 // ERROR "system register is not writable"
|
||||||
|
MSR R6, PMMIR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, PMSIDR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, REVIDR_EL1 // ERROR "system register is not writable"
|
||||||
|
MSR R6, RNDR // ERROR "system register is not writable"
|
||||||
|
MRS DBGDTRTX_EL0, R5 // ERROR "system register is not readable"
|
||||||
|
MRS ICV_DIR_EL1, R5 // ERROR "system register is not readable"
|
||||||
|
MRS ICC_SGI1R_EL1, R5 // ERROR "system register is not readable"
|
||||||
|
MRS ICC_SGI0R_EL1, R5 // ERROR "system register is not readable"
|
||||||
|
MRS ICC_EOIR1_EL1, R5 // ERROR "system register is not readable"
|
||||||
|
MRS ICC_EOIR0_EL1, R5 // ERROR "system register is not readable"
|
||||||
|
MRS ICC_DIR_EL1, R5 // ERROR "system register is not readable"
|
||||||
|
MRS ICC_ASGI1R_EL1, R5 // ERROR "system register is not readable"
|
||||||
|
MRS ICV_EOIR0_EL1, R3 // ERROR "system register is not readable"
|
||||||
|
MRS ICV_EOIR1_EL1, R3 // ERROR "system register is not readable"
|
||||||
|
MRS PMSWINC_EL0, R3 // ERROR "system register is not readable"
|
||||||
|
MRS OSLAR_EL1, R3 // ERROR "system register is not readable"
|
||||||
RET
|
RET
|
||||||
|
|
|
||||||
408
src/cmd/asm/internal/asm/testdata/mips64.s
vendored
408
src/cmd/asm/internal/asm/testdata/mips64.s
vendored
|
|
@ -8,53 +8,161 @@
|
||||||
#include "../../../../../runtime/textflag.h"
|
#include "../../../../../runtime/textflag.h"
|
||||||
|
|
||||||
TEXT foo(SB),DUPOK|NOSPLIT,$0
|
TEXT foo(SB),DUPOK|NOSPLIT,$0
|
||||||
|
//
|
||||||
|
// branch
|
||||||
|
//
|
||||||
|
// LBRA rel
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &nullgen, 0, &$2);
|
||||||
|
// }
|
||||||
|
BEQ R1, 2(PC)
|
||||||
|
label0:
|
||||||
|
JMP 1(PC) // JMP 1(PC) // 10000001
|
||||||
|
BEQ R1, 2(PC)
|
||||||
|
JMP label0+0 // JMP 3 // 1000fffd
|
||||||
|
BEQ R1, 2(PC)
|
||||||
|
JAL 1(PC) // CALL 1(PC) // 0c00000e
|
||||||
|
BEQ R1, 2(PC)
|
||||||
|
JAL label0+0 // CALL 3 // 0c000006
|
||||||
|
|
||||||
|
// LBRA addr
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &nullgen, 0, &$2);
|
||||||
|
// }
|
||||||
|
BEQ R1, 2(PC)
|
||||||
|
JMP 0(R1) // JMP (R1) // 00200008
|
||||||
|
BEQ R1, 2(PC)
|
||||||
|
JMP foo+0(SB) // JMP foo(SB) // 08000018
|
||||||
|
BEQ R1, 2(PC)
|
||||||
|
JAL 0(R1) // CALL (R1) // 0020f809
|
||||||
|
BEQ R1, 2(PC)
|
||||||
|
JAL foo+0(SB) // CALL foo(SB) // 0c000020
|
||||||
|
|
||||||
|
//
|
||||||
|
// BEQ/BNE
|
||||||
|
//
|
||||||
|
// LBRA rreg ',' rel
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
|
// }
|
||||||
|
label1:
|
||||||
|
BEQ R1, 1(PC) // BEQ R1, 1(PC) // 10200001
|
||||||
|
BEQ R1, label1 // BEQ R1, 18 // 1020fffd
|
||||||
|
|
||||||
|
// LBRA rreg ',' sreg ',' rel
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
|
// }
|
||||||
|
label2:
|
||||||
|
BEQ R1, R2, 1(PC) // BEQ R1, R2, 1(PC) // 10220001
|
||||||
|
BEQ R1, R2, label2 // BEQ R1, R2, 20 // 1022fffd
|
||||||
|
|
||||||
|
//
|
||||||
|
// other integer conditional branch
|
||||||
|
//
|
||||||
|
// LBRA rreg ',' rel
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
|
// }
|
||||||
|
label3:
|
||||||
|
BLTZ R1, 1(PC) // BLTZ R1, 1(PC) // 04200001
|
||||||
|
BLTZ R1, label3 // BLTZ R1, 22 // 0420fffd
|
||||||
|
|
||||||
|
//
|
||||||
|
// floating point conditional branch
|
||||||
|
//
|
||||||
|
// LBRA rel
|
||||||
|
label4:
|
||||||
|
BFPT 1(PC) // BFPT 1(PC) // 4501000100000000
|
||||||
|
BFPT label4 // BFPT 24 // 4501fffd00000000
|
||||||
|
|
||||||
//inst:
|
//inst:
|
||||||
//
|
//
|
||||||
// load ints and bytes
|
// load ints and bytes
|
||||||
//
|
//
|
||||||
|
// LMOVV rreg ',' rreg
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
|
// }
|
||||||
|
MOVV R25, R17 // 00198825
|
||||||
|
MOVV R1, R2 // 00011025
|
||||||
|
MOVV LO, R1 // 00000812
|
||||||
|
MOVV HI, R1 // 00000810
|
||||||
|
MOVV R1, LO // 00200013
|
||||||
|
MOVV R1, HI // 00200011
|
||||||
|
|
||||||
|
|
||||||
// LMOVW rreg ',' rreg
|
// LMOVW rreg ',' rreg
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
// }
|
// }
|
||||||
MOVW R1, R2
|
MOVW R1, R2 // 00011004
|
||||||
MOVW LO, R1
|
MOVW LO, R1 // 00000812
|
||||||
MOVW HI, R1
|
MOVW HI, R1 // 00000810
|
||||||
MOVW R1, LO
|
MOVW R1, LO // 00200013
|
||||||
MOVW R1, HI
|
MOVW R1, HI // 00200011
|
||||||
MOVV R1, R2
|
MOVWU R14, R27 // 000ed83c001bd83e
|
||||||
MOVV LO, R1
|
|
||||||
MOVV HI, R1
|
// LMOVH rreg ',' rreg
|
||||||
MOVV R1, LO
|
// {
|
||||||
MOVV R1, HI
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
|
// }
|
||||||
|
MOVH R16, R27 // 0010dc00001bdc03
|
||||||
|
MOVHU R1, R3 // 3023ffff
|
||||||
|
|
||||||
|
// LMOVB rreg ',' rreg
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
|
// }
|
||||||
|
MOVB R8, R9 // 00084e0000094e03
|
||||||
|
MOVBU R12, R17 // 319100ff
|
||||||
|
|
||||||
|
// LMOVV addr ',' rreg
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
|
// }
|
||||||
|
MOVV foo<>+3(SB), R2
|
||||||
|
MOVV (R5), R18 // dcb20000
|
||||||
|
MOVV 8(R16), R4 // de040008
|
||||||
|
MOVV -32(R14), R1 // ddc1ffe0
|
||||||
|
LLV (R1), R2 // d0220000
|
||||||
|
|
||||||
// LMOVW addr ',' rreg
|
// LMOVW addr ',' rreg
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
// }
|
// }
|
||||||
MOVW foo<>+3(SB), R2
|
MOVW foo<>+3(SB), R2
|
||||||
MOVW 16(R1), R2
|
MOVW (R11), R22 // 8d760000
|
||||||
MOVW (R1), R2
|
MOVW 1(R9), R24 // 8d380001
|
||||||
MOVV foo<>+3(SB), R2
|
MOVW -17(R24), R8 // 8f08ffef
|
||||||
MOVV 16(R1), R2
|
MOVWU (R11), R22 // 9d760000
|
||||||
MOVV (R1), R2
|
MOVWU 1(R9), R24 // 9d380001
|
||||||
|
MOVWU -17(R24), R8 // 9f08ffef
|
||||||
|
LL (R1), R2 // c0220000
|
||||||
|
|
||||||
LL (R1), R2 // c0220000
|
// LMOVH addr ',' rreg
|
||||||
LLV (R1), R2 // d0220000
|
|
||||||
|
|
||||||
// LMOVB rreg ',' rreg
|
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
// }
|
// }
|
||||||
MOVB R1, R2
|
MOVH foo<>+3(SB), R2
|
||||||
|
MOVH (R20), R7 // 86870000
|
||||||
|
MOVH 54(R11), R26 // 857a0036
|
||||||
|
MOVH -42(R3), R20 // 8474ffd6
|
||||||
|
MOVHU (R20), R7 // 96870000
|
||||||
|
MOVHU 54(R11), R26 // 957a0036
|
||||||
|
MOVHU -42(R3), R20 // 9474ffd6
|
||||||
|
|
||||||
// LMOVB addr ',' rreg
|
// LMOVB addr ',' rreg
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
// }
|
// }
|
||||||
MOVB foo<>+3(SB), R2
|
MOVB foo<>+3(SB), R2
|
||||||
MOVB 16(R1), R2
|
MOVB (R4), R21 // 80950000
|
||||||
MOVB (R1), R2
|
MOVB 9(R19), R18 // 82720009
|
||||||
|
MOVB -10(R19), R18 // 8272fff6
|
||||||
|
MOVBU (R4), R21 // 90950000
|
||||||
|
MOVBU 9(R19), R18 // 92720009
|
||||||
|
MOVBU -10(R19), R18 // 9272fff6
|
||||||
|
|
||||||
//
|
//
|
||||||
// load floats
|
// load floats
|
||||||
|
|
@ -90,27 +198,51 @@ TEXT foo(SB),DUPOK|NOSPLIT,$0
|
||||||
//
|
//
|
||||||
// store ints and bytes
|
// store ints and bytes
|
||||||
//
|
//
|
||||||
|
// LMOVV rreg ',' addr
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
|
// }
|
||||||
|
MOVV R1, foo<>+3(SB)
|
||||||
|
MOVV R18, (R5) // fcb20000
|
||||||
|
MOVV R4, 8(R16) // fe040008
|
||||||
|
MOVV R1, -32(R14) // fdc1ffe0
|
||||||
|
SCV R1, (R2) // f0410000
|
||||||
|
|
||||||
// LMOVW rreg ',' addr
|
// LMOVW rreg ',' addr
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
// }
|
// }
|
||||||
MOVW R1, foo<>+3(SB)
|
MOVW R1, foo<>+3(SB)
|
||||||
MOVW R1, 16(R2)
|
MOVW R8, (R3) // ac680000
|
||||||
MOVW R1, (R2)
|
MOVW R11, 19(R2) // ac4b0013
|
||||||
MOVV R1, foo<>+3(SB)
|
MOVW R25, -89(R22) // aed9ffa7
|
||||||
MOVV R1, 16(R2)
|
MOVWU R8, (R3) // ac680000
|
||||||
MOVV R1, (R2)
|
MOVWU R11, 19(R2) // ac4b0013
|
||||||
|
MOVWU R25, -89(R22) // aed9ffa7
|
||||||
|
SC R1, (R2) // e0410000
|
||||||
|
|
||||||
SC R1, (R2) // e0410000
|
// LMOVH rreg ',' addr
|
||||||
SCV R1, (R2) // f0410000
|
// {
|
||||||
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
|
// }
|
||||||
|
MOVH R13, (R7) // a4ed0000
|
||||||
|
MOVH R10, 61(R23) // a6ea003d
|
||||||
|
MOVH R8, -33(R12) // a588ffdf
|
||||||
|
MOVHU R13, (R7) // a4ed0000
|
||||||
|
MOVHU R10, 61(R23) // a6ea003d
|
||||||
|
MOVHU R8, -33(R12) // a588ffdf
|
||||||
|
|
||||||
// LMOVB rreg ',' addr
|
// LMOVB rreg ',' addr
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
// }
|
// }
|
||||||
MOVB R1, foo<>+3(SB)
|
MOVB R1, foo<>+3(SB)
|
||||||
MOVB R1, 16(R2)
|
MOVB R5, -18(R4) // a085ffee
|
||||||
MOVB R1, (R2)
|
MOVB R10, 9(R13) // a1aa0009
|
||||||
|
MOVB R15, (R13) // a1af0000
|
||||||
|
MOVBU R5, -18(R4) // a085ffee
|
||||||
|
MOVBU R10, 9(R13) // a1aa0009
|
||||||
|
MOVBU R15, (R13) // a1af0000
|
||||||
|
|
||||||
//
|
//
|
||||||
// store floats
|
// store floats
|
||||||
|
|
@ -130,27 +262,27 @@ TEXT foo(SB),DUPOK|NOSPLIT,$0
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
// }
|
// }
|
||||||
MOVW FCR0, R1
|
MOVW FCR31, R1 // 4441f800
|
||||||
|
|
||||||
// LMOVW freg ',' fpscr
|
// LMOVW freg ',' fpscr
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
// }
|
// }
|
||||||
MOVW R1, FCR0
|
MOVW R1, FCR31 // 44c1f800
|
||||||
|
|
||||||
// LMOVW rreg ',' mreg
|
// LMOVW rreg ',' mreg
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
// }
|
// }
|
||||||
MOVW R1, M1
|
MOVW R1, M1 // 40810800
|
||||||
MOVV R1, M1
|
MOVV R1, M1 // 40a10800
|
||||||
|
|
||||||
// LMOVW mreg ',' rreg
|
// LMOVW mreg ',' rreg
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
// }
|
// }
|
||||||
MOVW M1, R1
|
MOVW M1, R1 // 40010800
|
||||||
MOVV M1, R1
|
MOVV M1, R1 // 40210800
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -163,56 +295,169 @@ TEXT foo(SB),DUPOK|NOSPLIT,$0
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, int($4), &$6);
|
// outcode(int($1), &$2, int($4), &$6);
|
||||||
// }
|
// }
|
||||||
ADD R1, R2, R3
|
ADD R5, R9, R10 // 01255020
|
||||||
|
ADDU R13, R14, R19 // 01cd9821
|
||||||
|
ADDV R5, R9, R10 // 0125502c
|
||||||
|
ADDVU R13, R14, R19 // 01cd982d
|
||||||
|
|
||||||
// LADDW imm ',' sreg ',' rreg
|
// LADDW imm ',' sreg ',' rreg
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, int($4), &$6);
|
// outcode(int($1), &$2, int($4), &$6);
|
||||||
// }
|
// }
|
||||||
ADD $1, R2, R3
|
ADD $15176, R14, R9 // 21c93b48
|
||||||
|
ADD $-9, R5, R8 // 20a8fff7
|
||||||
|
ADDU $10, R9, R9 // 2529000a
|
||||||
|
ADDV $15176, R14, R9 // 61c93b48
|
||||||
|
ADDV $-9, R5, R8 // 60a8fff7
|
||||||
|
ADDVU $10, R9, R9 // 6529000a
|
||||||
|
|
||||||
// LADDW rreg ',' rreg
|
// LADDW rreg ',' rreg
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
// }
|
// }
|
||||||
ADD R1, R2
|
ADD R1, R2 // 00411020
|
||||||
|
ADDU R1, R2 // 00411021
|
||||||
|
ADDV R1, R2 // 0041102c
|
||||||
|
ADDVU R1, R2 // 0041102d
|
||||||
|
|
||||||
// LADDW imm ',' rreg
|
// LADDW imm ',' rreg
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
// }
|
// }
|
||||||
ADD $4, R1
|
ADD $4, R1 // 20210004
|
||||||
|
ADDV $4, R1 // 60210004
|
||||||
|
ADDU $4, R1 // 24210004
|
||||||
|
ADDVU $4, R1 // 64210004
|
||||||
|
ADD $-7193, R24 // 2318e3e7
|
||||||
|
ADDV $-7193, R24 // 6318e3e7
|
||||||
|
|
||||||
|
// LSUBW rreg ',' sreg ',' rreg
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &$2, int($4), &$6);
|
||||||
|
// }
|
||||||
|
SUB R6, R26, R27 // 0346d822
|
||||||
|
SUBU R6, R26, R27 // 0346d823
|
||||||
|
SUBV R16, R17, R26 // 0230d02e
|
||||||
|
SUBVU R16, R17, R26 // 0230d02f
|
||||||
|
|
||||||
|
// LSUBW imm ',' sreg ',' rreg
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &$2, int($4), &$6);
|
||||||
|
// }
|
||||||
|
SUB $-3126, R17, R22 // 22360c36
|
||||||
|
SUB $3126, R17, R22 // 2236f3ca
|
||||||
|
SUBU $16384, R17, R12 // 262cc000
|
||||||
|
SUBV $-6122, R10, R9 // 614917ea
|
||||||
|
SUBV $6122, R10, R9 // 6149e816
|
||||||
|
SUBVU $1203, R17, R12 // 662cfb4d
|
||||||
|
|
||||||
|
// LSUBW rreg ',' rreg
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
|
// }
|
||||||
|
SUB R14, R13 // 01ae6822
|
||||||
|
SUBU R14, R13 // 01ae6823
|
||||||
|
SUBV R4, R3 // 0064182e
|
||||||
|
SUBVU R4, R3 // 0064182f
|
||||||
|
// LSUBW imm ',' rreg
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
|
// }
|
||||||
|
SUB $6512, R13 // 21ade690
|
||||||
|
SUB $-6512, R13 // 21ad1970
|
||||||
|
SUBU $6512, R13 // 25ade690
|
||||||
|
SUBV $9531, R16 // 6210dac5
|
||||||
|
SUBV $-9531, R13 // 61ad253b
|
||||||
|
SUBVU $9531, R16 // 6610dac5
|
||||||
|
|
||||||
// LMUL rreg ',' rreg
|
// LMUL rreg ',' rreg
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
// }
|
// }
|
||||||
MUL R1, R2
|
MUL R19, R8 // 01130018
|
||||||
|
MULU R21, R13 // 01b50019
|
||||||
|
MULV R19, R8 // 0113001c
|
||||||
|
MULVU R21, R13 // 01b5001d
|
||||||
|
|
||||||
|
// LDIV rreg ',' rreg
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
|
// }
|
||||||
|
DIV R18, R22 // 02d2001a
|
||||||
|
DIVU R14, R9 // 012e001b
|
||||||
|
DIVV R8, R13 // 01a8001e
|
||||||
|
DIVVU R16, R19 // 0270001f
|
||||||
|
|
||||||
|
// LREM rreg ',' rreg
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
|
// }
|
||||||
|
REM R18, R22 // 02d2001a
|
||||||
|
REMU R14, R9 // 012e001b
|
||||||
|
REMV R8, R13 // 01a8001e
|
||||||
|
REMVU R16, R19 // 0270001f
|
||||||
|
|
||||||
// LSHW rreg ',' sreg ',' rreg
|
// LSHW rreg ',' sreg ',' rreg
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, int($4), &$6);
|
// outcode(int($1), &$2, int($4), &$6);
|
||||||
// }
|
// }
|
||||||
SLL R1, R2, R3
|
SLL R1, R2, R3 // 00221804
|
||||||
|
SLLV R10, R22, R21 // 0156a814
|
||||||
|
SRL R27, R6, R17 // 03668806
|
||||||
|
SRLV R27, R6, R17 // 03668816
|
||||||
|
SRA R11, R19, R20 // 0173a007
|
||||||
|
SRAV R20, R19, R19 // 02939817
|
||||||
|
|
||||||
// LSHW rreg ',' rreg
|
// LSHW rreg ',' rreg
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
// }
|
// }
|
||||||
SLL R1, R2
|
SLL R1, R2 // 00221004
|
||||||
|
SLLV R10, R22 // 0156b014
|
||||||
|
SRL R27, R6 // 03663006
|
||||||
|
SRLV R27, R6 // 03663016
|
||||||
|
SRA R11, R19 // 01739807
|
||||||
|
SRAV R20, R19 // 02939817
|
||||||
|
|
||||||
// LSHW imm ',' sreg ',' rreg
|
// LSHW imm ',' sreg ',' rreg
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, int($4), &$6);
|
// outcode(int($1), &$2, int($4), &$6);
|
||||||
// }
|
// }
|
||||||
SLL $4, R1, R2
|
SLL $19, R22, R21 // 0016acc0
|
||||||
|
SLLV $19, R22, R21 // 0016acf8
|
||||||
|
SRL $31, R6, R17 // 00068fc2
|
||||||
|
SRLV $31, R6, R17 // 00068ffa
|
||||||
|
SRA $8, R8, R19 // 00089a03
|
||||||
|
SRAV $19, R8, R7 // 00083cfb
|
||||||
|
|
||||||
// LSHW imm ',' rreg
|
// LSHW imm ',' rreg
|
||||||
// {
|
// {
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
// }
|
// }
|
||||||
SLL $4, R1
|
SLL $19, R21 // 0015acc0
|
||||||
|
SLLV $19, R21 // 0015acf8
|
||||||
|
SRL $31, R17 // 00118fc2
|
||||||
|
SRLV $31, R17 // 00118ffa
|
||||||
|
SRA $3, R12 // 000c60c3
|
||||||
|
SRAV $12, R3 // 00031b3b
|
||||||
|
|
||||||
|
|
||||||
|
// LAND/LXOR/LNOR/LOR rreg ',' rreg
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
|
// }
|
||||||
|
AND R14, R8 // 010e4024
|
||||||
|
XOR R15, R9 // 012f4826
|
||||||
|
NOR R16, R10 // 01505027
|
||||||
|
OR R17, R11 // 01715825
|
||||||
|
|
||||||
|
// LAND/LXOR/LOR imm ',' rreg
|
||||||
|
// {
|
||||||
|
// outcode(int($1), &$2, 0, &$4);
|
||||||
|
// }
|
||||||
|
AND $11, R17, R7 // 3227000b
|
||||||
|
XOR $341, R1, R23 // 38370155
|
||||||
|
OR $254, R25, R13 // 372d00fe
|
||||||
//
|
//
|
||||||
// move immediate: macro for lui+or, addi, addis, and other combinations
|
// move immediate: macro for lui+or, addi, addis, and other combinations
|
||||||
//
|
//
|
||||||
|
|
@ -232,76 +477,6 @@ TEXT foo(SB),DUPOK|NOSPLIT,$0
|
||||||
MOVV $1, R1
|
MOVV $1, R1
|
||||||
MOVV $foo(SB), R1
|
MOVV $foo(SB), R1
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// branch
|
|
||||||
//
|
|
||||||
// LBRA rel
|
|
||||||
// {
|
|
||||||
// outcode(int($1), &nullgen, 0, &$2);
|
|
||||||
// }
|
|
||||||
BEQ R1, 2(PC)
|
|
||||||
label0:
|
|
||||||
JMP 1(PC)
|
|
||||||
BEQ R1, 2(PC)
|
|
||||||
JMP label0+0 // JMP 68
|
|
||||||
BEQ R1, 2(PC)
|
|
||||||
JAL 1(PC) // CALL 1(PC)
|
|
||||||
BEQ R1, 2(PC)
|
|
||||||
JAL label0+0 // CALL 68
|
|
||||||
|
|
||||||
// LBRA addr
|
|
||||||
// {
|
|
||||||
// outcode(int($1), &nullgen, 0, &$2);
|
|
||||||
// }
|
|
||||||
BEQ R1, 2(PC)
|
|
||||||
JMP 0(R1) // JMP (R1)
|
|
||||||
BEQ R1, 2(PC)
|
|
||||||
JMP foo+0(SB) // JMP foo(SB)
|
|
||||||
BEQ R1, 2(PC)
|
|
||||||
JAL 0(R1) // CALL (R1)
|
|
||||||
BEQ R1, 2(PC)
|
|
||||||
JAL foo+0(SB) // CALL foo(SB)
|
|
||||||
|
|
||||||
//
|
|
||||||
// BEQ/BNE
|
|
||||||
//
|
|
||||||
// LBRA rreg ',' rel
|
|
||||||
// {
|
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
|
||||||
// }
|
|
||||||
label1:
|
|
||||||
BEQ R1, 1(PC)
|
|
||||||
BEQ R1, label1 // BEQ R1, 83
|
|
||||||
|
|
||||||
// LBRA rreg ',' sreg ',' rel
|
|
||||||
// {
|
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
|
||||||
// }
|
|
||||||
label2:
|
|
||||||
BEQ R1, R2, 1(PC)
|
|
||||||
BEQ R1, R2, label2 // BEQ R1, R2, 85
|
|
||||||
|
|
||||||
//
|
|
||||||
// other integer conditional branch
|
|
||||||
//
|
|
||||||
// LBRA rreg ',' rel
|
|
||||||
// {
|
|
||||||
// outcode(int($1), &$2, 0, &$4);
|
|
||||||
// }
|
|
||||||
label3:
|
|
||||||
BLTZ R1, 1(PC)
|
|
||||||
BLTZ R1, label3 // BLTZ R1, 87
|
|
||||||
|
|
||||||
//
|
|
||||||
// floating point conditional branch
|
|
||||||
//
|
|
||||||
// LBRA rel
|
|
||||||
label4:
|
|
||||||
BFPT 1(PC)
|
|
||||||
BFPT label4 // BFPT 89
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// floating point operate
|
// floating point operate
|
||||||
//
|
//
|
||||||
|
|
@ -406,6 +581,7 @@ label4:
|
||||||
|
|
||||||
NEGW R1, R2 // 00011023
|
NEGW R1, R2 // 00011023
|
||||||
NEGV R1, R2 // 0001102f
|
NEGV R1, R2 // 0001102f
|
||||||
|
RET
|
||||||
|
|
||||||
// END
|
// END
|
||||||
//
|
//
|
||||||
|
|
|
||||||
23
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
23
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
|
|
@ -900,6 +900,13 @@ label1:
|
||||||
// <mnemonic> VRT,VRA,VRB,SHB
|
// <mnemonic> VRT,VRA,VRB,SHB
|
||||||
VSLDOI $4, V2, V1, V0
|
VSLDOI $4, V2, V1, V0
|
||||||
|
|
||||||
|
// Vector merge odd and even word
|
||||||
|
// <MNEMONIC> VRA,VRB,VRT produces
|
||||||
|
// <mnemonic> VRT,VRA,VRB
|
||||||
|
|
||||||
|
VMRGOW V4,V5,V6
|
||||||
|
VMRGEW V4,V5,V6
|
||||||
|
|
||||||
// Vector count, VX-form
|
// Vector count, VX-form
|
||||||
// <MNEMONIC> VRB,VRT produces
|
// <MNEMONIC> VRB,VRT produces
|
||||||
// <mnemonic> VRT,VRB
|
// <mnemonic> VRT,VRB
|
||||||
|
|
@ -1004,20 +1011,34 @@ label1:
|
||||||
// <MNEMONIC> (RB)(RA*1),XT produces
|
// <MNEMONIC> (RB)(RA*1),XT produces
|
||||||
// <mnemonic> XT,RA,RB
|
// <mnemonic> XT,RA,RB
|
||||||
LXVD2X (R1)(R2*1), VS0
|
LXVD2X (R1)(R2*1), VS0
|
||||||
LXVDSX (R1)(R2*1), VS0
|
|
||||||
LXVW4X (R1)(R2*1), VS0
|
LXVW4X (R1)(R2*1), VS0
|
||||||
|
LXVH8X (R1)(R2*1), VS0
|
||||||
|
LXVB16X (R1)(R2*1), VS0
|
||||||
|
LXVDSX (R1)(R2*1), VS0
|
||||||
LXSDX (R1)(R2*1), VS0
|
LXSDX (R1)(R2*1), VS0
|
||||||
LXSIWAX (R1)(R2*1), VS0
|
LXSIWAX (R1)(R2*1), VS0
|
||||||
LXSIWZX (R1)(R2*1), VS0
|
LXSIWZX (R1)(R2*1), VS0
|
||||||
|
|
||||||
|
// VSX load, DQ-form
|
||||||
|
// <MNEMONIC> DQ(RA), XS produces
|
||||||
|
// <mnemonic> XS, DQ(RA)
|
||||||
|
LXV 32752(R1), VS0
|
||||||
|
|
||||||
// VSX store, XX1-form
|
// VSX store, XX1-form
|
||||||
// <MNEMONIC> XS,(RB)(RA*1) produces
|
// <MNEMONIC> XS,(RB)(RA*1) produces
|
||||||
// <mnemonic> XS,RA,RB
|
// <mnemonic> XS,RA,RB
|
||||||
STXVD2X VS63, (R1)(R2*1)
|
STXVD2X VS63, (R1)(R2*1)
|
||||||
STXVW4X VS63, (R1)(R2*1)
|
STXVW4X VS63, (R1)(R2*1)
|
||||||
|
STXVH8X VS63, (R1)(R2*1)
|
||||||
|
STXVB16X VS63, (R1)(R2*1)
|
||||||
STXSDX VS63, (R1)(R2*1)
|
STXSDX VS63, (R1)(R2*1)
|
||||||
STXSIWX VS63, (R1)(R2*1)
|
STXSIWX VS63, (R1)(R2*1)
|
||||||
|
|
||||||
|
// VSX store, DQ-form
|
||||||
|
// <MNEMONIC> DQ(RA), XS produces
|
||||||
|
// <mnemonic> XS, DQ(RA)
|
||||||
|
STXV VS63, -32752(R1)
|
||||||
|
|
||||||
// VSX move from VSR, XX1-form
|
// VSX move from VSR, XX1-form
|
||||||
// <MNEMONIC> XS,RA produces
|
// <MNEMONIC> XS,RA produces
|
||||||
// <mnemonic> RA,XS
|
// <mnemonic> RA,XS
|
||||||
|
|
|
||||||
269
src/cmd/asm/internal/asm/testdata/riscvenc.s
vendored
Normal file
269
src/cmd/asm/internal/asm/testdata/riscvenc.s
vendored
Normal file
|
|
@ -0,0 +1,269 @@
|
||||||
|
// 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 $1048575, X10 // 17f5ffff
|
||||||
|
|
||||||
|
LUI $0, X15 // b7070000
|
||||||
|
LUI $167, X15 // b7770a00
|
||||||
|
LUI $1048575, X15 // b7f7ffff
|
||||||
|
|
||||||
|
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 // eff2dff0
|
||||||
|
JALR X6, (X5) // 67830200
|
||||||
|
JALR X6, 4(X5) // 67834200
|
||||||
|
BEQ X5, X6, start // BEQ X5, X6, 2 // e38062f0
|
||||||
|
BNE X5, X6, start // BNE X5, X6, 2 // e39e62ee
|
||||||
|
BLT X5, X6, start // BLT X5, X6, 2 // e3cc62ee
|
||||||
|
BLTU X5, X6, start // BLTU X5, X6, 2 // e3ea62ee
|
||||||
|
BGE X5, X6, start // BGE X5, X6, 2 // e3d862ee
|
||||||
|
BGEU X5, X6, start // BGEU X5, X6, 2 // e3f662ee
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
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
|
||||||
134
src/cmd/asm/internal/asm/testdata/s390x.s
vendored
134
src/cmd/asm/internal/asm/testdata/s390x.s
vendored
|
|
@ -22,6 +22,9 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
||||||
MOVDLT R8, R9 // b9e24098
|
MOVDLT R8, R9 // b9e24098
|
||||||
MOVDNE R10, R11 // b9e270ba
|
MOVDNE R10, R11 // b9e270ba
|
||||||
|
|
||||||
|
LOCR $3, R2, R1 // b9f23012
|
||||||
|
LOCGR $7, R5, R6 // b9e27065
|
||||||
|
|
||||||
MOVD (R15), R1 // e310f0000004
|
MOVD (R15), R1 // e310f0000004
|
||||||
MOVW (R15), R2 // e320f0000014
|
MOVW (R15), R2 // e320f0000014
|
||||||
MOVH (R15), R3 // e330f0000015
|
MOVH (R15), R3 // e330f0000015
|
||||||
|
|
@ -33,12 +36,12 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
||||||
MOVWBR (R15), R9 // e390f000001e
|
MOVWBR (R15), R9 // e390f000001e
|
||||||
|
|
||||||
MOVD R1, n-8(SP) // e310f0100024
|
MOVD R1, n-8(SP) // e310f0100024
|
||||||
MOVW R2, n-8(SP) // e320f0100050
|
MOVW R2, n-8(SP) // 5020f010
|
||||||
MOVH R3, n-8(SP) // e330f0100070
|
MOVH R3, n-8(SP) // 4030f010
|
||||||
MOVB R4, n-8(SP) // e340f0100072
|
MOVB R4, n-8(SP) // 4240f010
|
||||||
MOVWZ R5, n-8(SP) // e350f0100050
|
MOVWZ R5, n-8(SP) // 5050f010
|
||||||
MOVHZ R6, n-8(SP) // e360f0100070
|
MOVHZ R6, n-8(SP) // 4060f010
|
||||||
MOVBZ R7, n-8(SP) // e370f0100072
|
MOVBZ R7, n-8(SP) // 4270f010
|
||||||
MOVDBR R8, n-8(SP) // e380f010002f
|
MOVDBR R8, n-8(SP) // e380f010002f
|
||||||
MOVWBR R9, n-8(SP) // e390f010003e
|
MOVWBR R9, n-8(SP) // e390f010003e
|
||||||
|
|
||||||
|
|
@ -58,6 +61,20 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
||||||
MOVB $-128, -524288(R5) // eb8050008052
|
MOVB $-128, -524288(R5) // eb8050008052
|
||||||
MOVB $1, -524289(R6) // c0a1fff7ffff41aa60009201a000
|
MOVB $1, -524289(R6) // c0a1fff7ffff41aa60009201a000
|
||||||
|
|
||||||
|
// RX (12-bit displacement) and RXY (20-bit displacement) instruction encoding (e.g: ST vs STY)
|
||||||
|
MOVW R1, 4095(R2)(R3) // 50132fff
|
||||||
|
MOVW R1, 4096(R2)(R3) // e31320000150
|
||||||
|
MOVWZ R1, 4095(R2)(R3) // 50132fff
|
||||||
|
MOVWZ R1, 4096(R2)(R3) // e31320000150
|
||||||
|
MOVH R1, 4095(R2)(R3) // 40132fff
|
||||||
|
MOVHZ R1, 4095(R2)(R3) // 40132fff
|
||||||
|
MOVH R1, 4096(R2)(R3) // e31320000170
|
||||||
|
MOVHZ R1, 4096(R2)(R3) // e31320000170
|
||||||
|
MOVB R1, 4095(R2)(R3) // 42132fff
|
||||||
|
MOVBZ R1, 4095(R2)(R3) // 42132fff
|
||||||
|
MOVB R1, 4096(R2)(R3) // e31320000172
|
||||||
|
MOVBZ R1, 4096(R2)(R3) // e31320000172
|
||||||
|
|
||||||
ADD R1, R2 // b9e81022
|
ADD R1, R2 // b9e81022
|
||||||
ADD R1, R2, R3 // b9e81032
|
ADD R1, R2, R3 // b9e81032
|
||||||
ADD $8192, R1 // a71b2000
|
ADD $8192, R1 // a71b2000
|
||||||
|
|
@ -95,6 +112,7 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
||||||
MULHD R7, R2, R1 // b90400b2b98600a7ebb7003f000ab98000b2b90900abebb2003f000ab98000b7b9e9b01a
|
MULHD R7, R2, R1 // b90400b2b98600a7ebb7003f000ab98000b2b90900abebb2003f000ab98000b7b9e9b01a
|
||||||
MULHDU R3, R4 // b90400b4b98600a3b904004a
|
MULHDU R3, R4 // b90400b4b98600a3b904004a
|
||||||
MULHDU R5, R6, R7 // b90400b6b98600a5b904007a
|
MULHDU R5, R6, R7 // b90400b6b98600a5b904007a
|
||||||
|
MLGR R1, R2 // b9860021
|
||||||
DIVD R1, R2 // b90400b2b90d00a1b904002b
|
DIVD R1, R2 // b90400b2b90d00a1b904002b
|
||||||
DIVD R1, R2, R3 // b90400b2b90d00a1b904003b
|
DIVD R1, R2, R3 // b90400b2b90d00a1b904003b
|
||||||
DIVW R4, R5 // b90400b5b91d00a4b904005b
|
DIVW R4, R5 // b90400b5b91d00a4b904005b
|
||||||
|
|
@ -183,6 +201,24 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
||||||
XORW (R1), R2 // 57201000
|
XORW (R1), R2 // 57201000
|
||||||
XORW -1(R1), R2 // e3201fffff57
|
XORW -1(R1), R2 // e3201fffff57
|
||||||
|
|
||||||
|
// shift and rotate instructions
|
||||||
|
SRD $4, R4, R7 // eb740004000c
|
||||||
|
SRD R1, R4, R7 // eb741000000c
|
||||||
|
SRW $4, R4, R7 // eb74000400de
|
||||||
|
SRW R1, R4, R7 // eb74100000de
|
||||||
|
SLW $4, R3, R6 // eb63000400df
|
||||||
|
SLW R2, R3, R6 // eb63200000df
|
||||||
|
SLD $4, R3, R6 // eb630004000d
|
||||||
|
SLD R2, R3, R6 // eb632000000d
|
||||||
|
SRAD $4, R5, R8 // eb850004000a
|
||||||
|
SRAD R3, R5, R8 // eb853000000a
|
||||||
|
SRAW $4, R5, R8 // eb85000400dc
|
||||||
|
SRAW R3, R5, R8 // eb85300000dc
|
||||||
|
RLL R1, R2, R3 // eb321000001d
|
||||||
|
RLL $4, R2, R3 // eb320004001d
|
||||||
|
RLLG R1, R2, R3 // eb321000001c
|
||||||
|
RLLG $4, R2, R3 // eb320004001c
|
||||||
|
|
||||||
RNSBG $0, $31, $32, R1, R2 // ec21001f2054
|
RNSBG $0, $31, $32, R1, R2 // ec21001f2054
|
||||||
RXSBG $17, $8, $16, R3, R4 // ec4311081057
|
RXSBG $17, $8, $16, R3, R4 // ec4311081057
|
||||||
ROSBG $9, $24, $11, R5, R6 // ec6509180b56
|
ROSBG $9, $24, $11, R5, R6 // ec6509180b56
|
||||||
|
|
@ -209,6 +245,16 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
||||||
LAO R1, R2, (R3) // eb21300000f6
|
LAO R1, R2, (R3) // eb21300000f6
|
||||||
LAOG R4, R5, (R6) // eb54600000e6
|
LAOG R4, R5, (R6) // eb54600000e6
|
||||||
|
|
||||||
|
// load and store multiple
|
||||||
|
LMG n-8(SP), R3, R4 // eb34f0100004
|
||||||
|
LMG -5(R5), R3, R4 // eb345ffbff04
|
||||||
|
LMY n-8(SP), R3, R4 // 9834f010
|
||||||
|
LMY 4096(R1), R3, R4 // eb3410000198
|
||||||
|
STMG R1, R2, n-8(SP) // eb12f0100024
|
||||||
|
STMG R1, R2, -5(R3) // eb123ffbff24
|
||||||
|
STMY R1, R2, n-8(SP) // 9012f010
|
||||||
|
STMY R1, R2, 4096(R3) // eb1230000190
|
||||||
|
|
||||||
XC $8, (R15), n-8(SP) // d707f010f000
|
XC $8, (R15), n-8(SP) // d707f010f000
|
||||||
NC $8, (R15), n-8(SP) // d407f010f000
|
NC $8, (R15), n-8(SP) // d407f010f000
|
||||||
OC $8, (R15), n-8(SP) // d607f010f000
|
OC $8, (R15), n-8(SP) // d607f010f000
|
||||||
|
|
@ -238,6 +284,10 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
||||||
IPM R3 // b2220030
|
IPM R3 // b2220030
|
||||||
IPM R12 // b22200c0
|
IPM R12 // b22200c0
|
||||||
|
|
||||||
|
SPM R1 // 0410
|
||||||
|
SPM R10 // 04a0
|
||||||
|
|
||||||
|
BRC $7, 0(PC) // a7740000
|
||||||
BNE 0(PC) // a7740000
|
BNE 0(PC) // a7740000
|
||||||
BEQ 0(PC) // a7840000
|
BEQ 0(PC) // a7840000
|
||||||
BLT 0(PC) // a7440000
|
BLT 0(PC) // a7440000
|
||||||
|
|
@ -247,6 +297,9 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
||||||
BLTU 0(PC) // a7540000
|
BLTU 0(PC) // a7540000
|
||||||
BLEU 0(PC) // a7d40000
|
BLEU 0(PC) // a7d40000
|
||||||
|
|
||||||
|
BRCT R1, 0(PC) // a7160000
|
||||||
|
BRCTG R2, 0(PC) // a7270000
|
||||||
|
|
||||||
CMPBNE R1, R2, 0(PC) // ec1200007064
|
CMPBNE R1, R2, 0(PC) // ec1200007064
|
||||||
CMPBEQ R3, R4, 0(PC) // ec3400008064
|
CMPBEQ R3, R4, 0(PC) // ec3400008064
|
||||||
CMPBLT R5, R6, 0(PC) // ec5600004064
|
CMPBLT R5, R6, 0(PC) // ec5600004064
|
||||||
|
|
@ -275,6 +328,16 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
||||||
CMPUBGT R9, $256, 0(PC) // ec920000007d
|
CMPUBGT R9, $256, 0(PC) // ec920000007d
|
||||||
CMPUBGE R2, $0, 0(PC) // ec2a0000007d
|
CMPUBGE R2, $0, 0(PC) // ec2a0000007d
|
||||||
|
|
||||||
|
CRJ $15, R1, R2, 0(PC) // ec120000f076
|
||||||
|
CGRJ $12, R3, R4, 0(PC) // ec340000c064
|
||||||
|
CLRJ $3, R5, R6, 0(PC) // ec5600003077
|
||||||
|
CLGRJ $0, R7, R8, 0(PC) // ec7800000065
|
||||||
|
|
||||||
|
CIJ $4, R9, $127, 0(PC) // ec9400007f7e
|
||||||
|
CGIJ $8, R11, $-128, 0(PC) // ecb80000807c
|
||||||
|
CLIJ $1, R1, $255, 0(PC) // ec110000ff7f
|
||||||
|
CLGIJ $2, R3, $0, 0(PC) // ec320000007d
|
||||||
|
|
||||||
LGDR F1, R12 // b3cd00c1
|
LGDR F1, R12 // b3cd00c1
|
||||||
LDGR R2, F15 // b3c100f2
|
LDGR R2, F15 // b3c100f2
|
||||||
|
|
||||||
|
|
@ -300,10 +363,22 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
||||||
|
|
||||||
FMOVS $0, F11 // b37400b0
|
FMOVS $0, F11 // b37400b0
|
||||||
FMOVD $0, F12 // b37500c0
|
FMOVD $0, F12 // b37500c0
|
||||||
FMOVS (R1)(R2*1), F0 // ed0210000064
|
FMOVS (R1)(R2*1), F0 // 78021000
|
||||||
FMOVS n-8(SP), F15 // edf0f0100064
|
FMOVS n-8(SP), F15 // 78f0f010
|
||||||
FMOVD -9999999(R8)(R9*1), F8 // c0a1ff67698141aa9000ed8a80000065
|
FMOVD -9999999(R8)(R9*1), F8 // c0a1ff67698141aa9000688a8000
|
||||||
FMOVD F4, F5 // 2854
|
FMOVD F4, F5 // 2854
|
||||||
|
|
||||||
|
// RX (12-bit displacement) and RXY (20-bit displacement) instruction encoding (e.g. LD vs LDY)
|
||||||
|
FMOVD (R1), F0 // 68001000
|
||||||
|
FMOVD 4095(R2), F13 // 68d02fff
|
||||||
|
FMOVD 4096(R2), F15 // edf020000165
|
||||||
|
FMOVS 4095(R2)(R3), F13 // 78d32fff
|
||||||
|
FMOVS 4096(R2)(R4), F15 // edf420000164
|
||||||
|
FMOVD F0, 4095(R1) // 60001fff
|
||||||
|
FMOVD F0, 4096(R1) // ed0010000167
|
||||||
|
FMOVS F13, 4095(R2)(R3) // 70d32fff
|
||||||
|
FMOVS F13, 4096(R2)(R3) // edd320000166
|
||||||
|
|
||||||
FADDS F0, F15 // b30a00f0
|
FADDS F0, F15 // b30a00f0
|
||||||
FADD F1, F14 // b31a00e1
|
FADD F1, F14 // b31a00e1
|
||||||
FSUBS F2, F13 // b30b00d2
|
FSUBS F2, F13 // b30b00d2
|
||||||
|
|
@ -329,6 +404,32 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
||||||
TCEB F5, $8 // ed5000080010
|
TCEB F5, $8 // ed5000080010
|
||||||
TCDB F15, $4095 // edf00fff0011
|
TCDB F15, $4095 // edf00fff0011
|
||||||
|
|
||||||
|
UNDEF // 00000000
|
||||||
|
NOPH // 0700
|
||||||
|
|
||||||
|
// vector add and sub instructions
|
||||||
|
VAB V3, V4, V4 // e743400000f3
|
||||||
|
VAH V3, V4, V4 // e743400010f3
|
||||||
|
VAF V3, V4, V4 // e743400020f3
|
||||||
|
VAG V3, V4, V4 // e743400030f3
|
||||||
|
VAQ V3, V4, V4 // e743400040f3
|
||||||
|
VAB V1, V2 // e721200000f3
|
||||||
|
VAH V1, V2 // e721200010f3
|
||||||
|
VAF V1, V2 // e721200020f3
|
||||||
|
VAG V1, V2 // e721200030f3
|
||||||
|
VAQ V1, V2 // e721200040f3
|
||||||
|
VSB V3, V4, V4 // e744300000f7
|
||||||
|
VSH V3, V4, V4 // e744300010f7
|
||||||
|
VSF V3, V4, V4 // e744300020f7
|
||||||
|
VSG V3, V4, V4 // e744300030f7
|
||||||
|
VSQ V3, V4, V4 // e744300040f7
|
||||||
|
VSB V1, V2 // e722100000f7
|
||||||
|
VSH V1, V2 // e722100010f7
|
||||||
|
VSF V1, V2 // e722100020f7
|
||||||
|
VSG V1, V2 // e722100030f7
|
||||||
|
VSQ V1, V2 // e722100040f7
|
||||||
|
|
||||||
|
VCEQB V1, V3, V3 // e731300000f8
|
||||||
VL (R15), V1 // e710f0000006
|
VL (R15), V1 // e710f0000006
|
||||||
VST V1, (R15) // e710f000000e
|
VST V1, (R15) // e710f000000e
|
||||||
VL (R15), V31 // e7f0f0000806
|
VL (R15), V31 // e7f0f0000806
|
||||||
|
|
@ -352,9 +453,16 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
||||||
VFEEZBS V1, V2, V31 // e7f120300880
|
VFEEZBS V1, V2, V31 // e7f120300880
|
||||||
WFCHDBS V22, V23, V4 // e746701836eb
|
WFCHDBS V22, V23, V4 // e746701836eb
|
||||||
VMNH V1, V2, V30 // e7e1200018fe
|
VMNH V1, V2, V30 // e7e1200018fe
|
||||||
VO V2, V1, V0 // e7021000006a
|
|
||||||
VERLLVF V2, V30, V27 // e7be20002c73
|
VERLLVF V2, V30, V27 // e7be20002c73
|
||||||
VSCBIB V0, V23, V24 // e78700000cf5
|
VSCBIB V0, V23, V24 // e78700000cf5
|
||||||
|
VN V2, V1, V0 // e70210000068
|
||||||
|
VNC V2, V1, V0 // e70210000069
|
||||||
|
VO V2, V1, V0 // e7021000006a
|
||||||
|
VX V2, V1, V0 // e7021000006d
|
||||||
|
VN V16, V1 // e71010000468
|
||||||
|
VNC V16, V1 // e71010000469
|
||||||
|
VO V16, V1 // e7101000046a
|
||||||
|
VX V16, V1 // e7101000046d
|
||||||
VNOT V16, V1 // e7101000046b
|
VNOT V16, V1 // e7101000046b
|
||||||
VCLZF V16, V17 // e71000002c53
|
VCLZF V16, V17 // e71000002c53
|
||||||
VLVGP R3, R4, V8 // e78340000062
|
VLVGP R3, R4, V8 // e78340000062
|
||||||
|
|
@ -391,6 +499,12 @@ TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-
|
||||||
VMSLEG V21, V22, V23, V24 // e78563807fb8
|
VMSLEG V21, V22, V23, V24 // e78563807fb8
|
||||||
VMSLOG V21, V22, V23, V24 // e78563407fb8
|
VMSLOG V21, V22, V23, V24 // e78563407fb8
|
||||||
VMSLEOG V21, V22, V23, V24 // e78563c07fb8
|
VMSLEOG V21, V22, V23, V24 // e78563c07fb8
|
||||||
|
VSUMGH V1, V2, V3 // e73120001065
|
||||||
|
VSUMGF V16, V17, V18 // e72010002e65
|
||||||
|
VSUMQF V4, V5, V6 // e76450002067
|
||||||
|
VSUMQG V19, V20, V21 // e75340003e67
|
||||||
|
VSUMB V7, V8, V9 // e79780000064
|
||||||
|
VSUMH V22, V23, V24 // e78670001e64
|
||||||
|
|
||||||
RET
|
RET
|
||||||
RET foo(SB)
|
RET foo(SB)
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ var (
|
||||||
Dynlink = flag.Bool("dynlink", false, "support references to Go symbols defined in other shared libraries")
|
Dynlink = flag.Bool("dynlink", false, "support references to Go symbols defined in other shared libraries")
|
||||||
AllErrors = flag.Bool("e", false, "no limit on number of errors reported")
|
AllErrors = flag.Bool("e", false, "no limit on number of errors reported")
|
||||||
SymABIs = flag.Bool("gensymabis", false, "write symbol ABI information to output file, don't assemble")
|
SymABIs = flag.Bool("gensymabis", false, "write symbol ABI information to output file, don't assemble")
|
||||||
|
Newobj = flag.Bool("newobj", false, "use new object file format")
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
|
|
@ -40,18 +40,18 @@ func main() {
|
||||||
}
|
}
|
||||||
ctxt.Flag_dynlink = *flags.Dynlink
|
ctxt.Flag_dynlink = *flags.Dynlink
|
||||||
ctxt.Flag_shared = *flags.Shared || *flags.Dynlink
|
ctxt.Flag_shared = *flags.Shared || *flags.Dynlink
|
||||||
|
ctxt.Flag_newobj = *flags.Newobj
|
||||||
ctxt.Bso = bufio.NewWriter(os.Stdout)
|
ctxt.Bso = bufio.NewWriter(os.Stdout)
|
||||||
defer ctxt.Bso.Flush()
|
defer ctxt.Bso.Flush()
|
||||||
|
|
||||||
architecture.Init(ctxt)
|
architecture.Init(ctxt)
|
||||||
|
|
||||||
// Create object file, write header.
|
// Create object file, write header.
|
||||||
out, err := os.Create(*flags.OutputFile)
|
buf, err := bio.Create(*flags.OutputFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
defer bio.MustClose(out)
|
defer buf.Close()
|
||||||
buf := bufio.NewWriter(bio.MustWriter(out))
|
|
||||||
|
|
||||||
if !*flags.SymABIs {
|
if !*flags.SymABIs {
|
||||||
fmt.Fprintf(buf, "go object %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version)
|
fmt.Fprintf(buf, "go object %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version)
|
||||||
|
|
@ -83,6 +83,7 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ok && !*flags.SymABIs {
|
if ok && !*flags.SymABIs {
|
||||||
|
ctxt.NumberSyms(true)
|
||||||
obj.WriteObjFile(ctxt, buf, "")
|
obj.WriteObjFile(ctxt, buf, "")
|
||||||
}
|
}
|
||||||
if !ok || diag {
|
if !ok || diag {
|
||||||
|
|
@ -91,9 +92,8 @@ func main() {
|
||||||
} else {
|
} else {
|
||||||
log.Print("assembly failed")
|
log.Print("assembly failed")
|
||||||
}
|
}
|
||||||
out.Close()
|
buf.Close()
|
||||||
os.Remove(*flags.OutputFile)
|
os.Remove(*flags.OutputFile)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
buf.Flush()
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ For example:
|
||||||
|
|
||||||
The default pkg-config tool may be changed by setting the PKG_CONFIG environment variable.
|
The default pkg-config tool may be changed by setting the PKG_CONFIG environment variable.
|
||||||
|
|
||||||
For security reasons, only a limited set of flags are allowed, notably -D, -I, and -l.
|
For security reasons, only a limited set of flags are allowed, notably -D, -U, -I, and -l.
|
||||||
To allow additional flags, set CGO_CFLAGS_ALLOW to a regular expression
|
To allow additional flags, set CGO_CFLAGS_ALLOW to a regular expression
|
||||||
matching the new flags. To disallow flags that would otherwise be allowed,
|
matching the new flags. To disallow flags that would otherwise be allowed,
|
||||||
set CGO_CFLAGS_DISALLOW to a regular expression matching arguments
|
set CGO_CFLAGS_DISALLOW to a regular expression matching arguments
|
||||||
|
|
@ -99,7 +99,7 @@ Will be expanded to:
|
||||||
|
|
||||||
When the Go tool sees that one or more Go files use the special import
|
When the Go tool sees that one or more Go files use the special import
|
||||||
"C", it will look for other non-Go files in the directory and compile
|
"C", it will look for other non-Go files in the directory and compile
|
||||||
them as part of the Go package. Any .c, .s, or .S files will be
|
them as part of the Go package. Any .c, .s, .S or .sx files will be
|
||||||
compiled with the C compiler. Any .cc, .cpp, or .cxx files will be
|
compiled with the C compiler. Any .cc, .cpp, or .cxx files will be
|
||||||
compiled with the C++ compiler. Any .f, .F, .for or .f90 files will be
|
compiled with the C++ compiler. Any .f, .F, .for or .f90 files will be
|
||||||
compiled with the fortran compiler. Any .h, .hh, .hpp, or .hxx files will
|
compiled with the fortran compiler. Any .h, .hh, .hpp, or .hxx files will
|
||||||
|
|
|
||||||
|
|
@ -816,7 +816,7 @@ func (p *Package) rewriteCall(f *File, call *Call) (string, bool) {
|
||||||
// Rewrite C.f(p) to
|
// Rewrite C.f(p) to
|
||||||
// func() {
|
// func() {
|
||||||
// _cgo0 := p
|
// _cgo0 := p
|
||||||
// _cgoCheckPointer(_cgo0)
|
// _cgoCheckPointer(_cgo0, nil)
|
||||||
// C.f(_cgo0)
|
// C.f(_cgo0)
|
||||||
// }()
|
// }()
|
||||||
// Using a function literal like this lets us evaluate the
|
// Using a function literal like this lets us evaluate the
|
||||||
|
|
@ -834,7 +834,7 @@ func (p *Package) rewriteCall(f *File, call *Call) (string, bool) {
|
||||||
// defer func() func() {
|
// defer func() func() {
|
||||||
// _cgo0 := p
|
// _cgo0 := p
|
||||||
// return func() {
|
// return func() {
|
||||||
// _cgoCheckPointer(_cgo0)
|
// _cgoCheckPointer(_cgo0, nil)
|
||||||
// C.f(_cgo0)
|
// C.f(_cgo0)
|
||||||
// }
|
// }
|
||||||
// }()()
|
// }()()
|
||||||
|
|
@ -921,7 +921,7 @@ func (p *Package) rewriteCall(f *File, call *Call) (string, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtPos(arg, origArg.Pos()))
|
fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtPos(arg, origArg.Pos()))
|
||||||
fmt.Fprintf(&sbCheck, "_cgoCheckPointer(_cgo%d); ", i)
|
fmt.Fprintf(&sbCheck, "_cgoCheckPointer(_cgo%d, nil); ", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
if call.Deferred {
|
if call.Deferred {
|
||||||
|
|
@ -2189,6 +2189,11 @@ func (c *typeConv) FinishType(pos token.Pos) {
|
||||||
// Type returns a *Type with the same memory layout as
|
// Type returns a *Type with the same memory layout as
|
||||||
// dtype when used as the type of a variable or a struct field.
|
// dtype when used as the type of a variable or a struct field.
|
||||||
func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
||||||
|
return c.loadType(dtype, pos, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadType recursively loads the requested dtype and its dependency graph.
|
||||||
|
func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Type {
|
||||||
// Always recompute bad pointer typedefs, as the set of such
|
// Always recompute bad pointer typedefs, as the set of such
|
||||||
// typedefs changes as we see more types.
|
// typedefs changes as we see more types.
|
||||||
checkCache := true
|
checkCache := true
|
||||||
|
|
@ -2196,7 +2201,9 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
||||||
checkCache = false
|
checkCache = false
|
||||||
}
|
}
|
||||||
|
|
||||||
key := dtype.String()
|
// The cache key should be relative to its parent.
|
||||||
|
// See issue https://golang.org/issue/31891
|
||||||
|
key := parent + " > " + dtype.String()
|
||||||
|
|
||||||
if checkCache {
|
if checkCache {
|
||||||
if t, ok := c.m[key]; ok {
|
if t, ok := c.m[key]; ok {
|
||||||
|
|
@ -2236,7 +2243,7 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
||||||
// Translate to zero-length array instead.
|
// Translate to zero-length array instead.
|
||||||
count = 0
|
count = 0
|
||||||
}
|
}
|
||||||
sub := c.Type(dt.Type, pos)
|
sub := c.loadType(dt.Type, pos, key)
|
||||||
t.Align = sub.Align
|
t.Align = sub.Align
|
||||||
t.Go = &ast.ArrayType{
|
t.Go = &ast.ArrayType{
|
||||||
Len: c.intExpr(count),
|
Len: c.intExpr(count),
|
||||||
|
|
@ -2381,7 +2388,7 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
||||||
c.ptrs[key] = append(c.ptrs[key], t)
|
c.ptrs[key] = append(c.ptrs[key], t)
|
||||||
|
|
||||||
case *dwarf.QualType:
|
case *dwarf.QualType:
|
||||||
t1 := c.Type(dt.Type, pos)
|
t1 := c.loadType(dt.Type, pos, key)
|
||||||
t.Size = t1.Size
|
t.Size = t1.Size
|
||||||
t.Align = t1.Align
|
t.Align = t1.Align
|
||||||
t.Go = t1.Go
|
t.Go = t1.Go
|
||||||
|
|
@ -2465,7 +2472,7 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
||||||
}
|
}
|
||||||
name := c.Ident("_Ctype_" + dt.Name)
|
name := c.Ident("_Ctype_" + dt.Name)
|
||||||
goIdent[name.Name] = name
|
goIdent[name.Name] = name
|
||||||
sub := c.Type(dt.Type, pos)
|
sub := c.loadType(dt.Type, pos, key)
|
||||||
if c.badPointerTypedef(dt) {
|
if c.badPointerTypedef(dt) {
|
||||||
// Treat this typedef as a uintptr.
|
// Treat this typedef as a uintptr.
|
||||||
s := *sub
|
s := *sub
|
||||||
|
|
|
||||||
|
|
@ -1631,14 +1631,14 @@ func _cgo_runtime_cgocall(unsafe.Pointer, uintptr) int32
|
||||||
func _cgo_runtime_cgocallback(unsafe.Pointer, unsafe.Pointer, uintptr, uintptr)
|
func _cgo_runtime_cgocallback(unsafe.Pointer, unsafe.Pointer, uintptr, uintptr)
|
||||||
|
|
||||||
//go:linkname _cgoCheckPointer runtime.cgoCheckPointer
|
//go:linkname _cgoCheckPointer runtime.cgoCheckPointer
|
||||||
func _cgoCheckPointer(interface{}, ...interface{})
|
func _cgoCheckPointer(interface{}, interface{})
|
||||||
|
|
||||||
//go:linkname _cgoCheckResult runtime.cgoCheckResult
|
//go:linkname _cgoCheckResult runtime.cgoCheckResult
|
||||||
func _cgoCheckResult(interface{})
|
func _cgoCheckResult(interface{})
|
||||||
`
|
`
|
||||||
|
|
||||||
const gccgoGoProlog = `
|
const gccgoGoProlog = `
|
||||||
func _cgoCheckPointer(interface{}, ...interface{})
|
func _cgoCheckPointer(interface{}, interface{})
|
||||||
|
|
||||||
func _cgoCheckResult(interface{})
|
func _cgoCheckResult(interface{})
|
||||||
`
|
`
|
||||||
|
|
@ -1825,16 +1825,16 @@ typedef struct __go_empty_interface {
|
||||||
void *__object;
|
void *__object;
|
||||||
} Eface;
|
} Eface;
|
||||||
|
|
||||||
extern void runtimeCgoCheckPointer(Eface, Slice)
|
extern void runtimeCgoCheckPointer(Eface, Eface)
|
||||||
__asm__("runtime.cgoCheckPointer")
|
__asm__("runtime.cgoCheckPointer")
|
||||||
__attribute__((weak));
|
__attribute__((weak));
|
||||||
|
|
||||||
extern void localCgoCheckPointer(Eface, Slice)
|
extern void localCgoCheckPointer(Eface, Eface)
|
||||||
__asm__("GCCGOSYMBOLPREF._cgoCheckPointer");
|
__asm__("GCCGOSYMBOLPREF._cgoCheckPointer");
|
||||||
|
|
||||||
void localCgoCheckPointer(Eface ptr, Slice args) {
|
void localCgoCheckPointer(Eface ptr, Eface arg) {
|
||||||
if(runtimeCgoCheckPointer) {
|
if(runtimeCgoCheckPointer) {
|
||||||
runtimeCgoCheckPointer(ptr, args);
|
runtimeCgoCheckPointer(ptr, arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ type File struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFormats(t *testing.T) {
|
func TestFormats(t *testing.T) {
|
||||||
if testing.Short() {
|
if testing.Short() && testenv.Builder() == "" {
|
||||||
t.Skip("Skipping in short mode")
|
t.Skip("Skipping in short mode")
|
||||||
}
|
}
|
||||||
testenv.MustHaveGoBuild(t) // more restrictive than necessary, but that's ok
|
testenv.MustHaveGoBuild(t) // more restrictive than necessary, but that's ok
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,12 @@ package main_test
|
||||||
// An empty new format means that the format should remain unchanged.
|
// An empty new format means that the format should remain unchanged.
|
||||||
var knownFormats = map[string]string{
|
var knownFormats = map[string]string{
|
||||||
"*bytes.Buffer %s": "",
|
"*bytes.Buffer %s": "",
|
||||||
|
"*cmd/compile/internal/gc.EscLocation %v": "",
|
||||||
"*cmd/compile/internal/gc.Mpflt %v": "",
|
"*cmd/compile/internal/gc.Mpflt %v": "",
|
||||||
"*cmd/compile/internal/gc.Mpint %v": "",
|
"*cmd/compile/internal/gc.Mpint %v": "",
|
||||||
"*cmd/compile/internal/gc.Node %#v": "",
|
"*cmd/compile/internal/gc.Node %#v": "",
|
||||||
"*cmd/compile/internal/gc.Node %+S": "",
|
"*cmd/compile/internal/gc.Node %+S": "",
|
||||||
"*cmd/compile/internal/gc.Node %+v": "",
|
"*cmd/compile/internal/gc.Node %+v": "",
|
||||||
"*cmd/compile/internal/gc.Node %0j": "",
|
|
||||||
"*cmd/compile/internal/gc.Node %L": "",
|
"*cmd/compile/internal/gc.Node %L": "",
|
||||||
"*cmd/compile/internal/gc.Node %S": "",
|
"*cmd/compile/internal/gc.Node %S": "",
|
||||||
"*cmd/compile/internal/gc.Node %j": "",
|
"*cmd/compile/internal/gc.Node %j": "",
|
||||||
|
|
@ -88,8 +88,6 @@ var knownFormats = map[string]string{
|
||||||
"cmd/compile/internal/gc.Class %v": "",
|
"cmd/compile/internal/gc.Class %v": "",
|
||||||
"cmd/compile/internal/gc.Ctype %d": "",
|
"cmd/compile/internal/gc.Ctype %d": "",
|
||||||
"cmd/compile/internal/gc.Ctype %v": "",
|
"cmd/compile/internal/gc.Ctype %v": "",
|
||||||
"cmd/compile/internal/gc.Level %d": "",
|
|
||||||
"cmd/compile/internal/gc.Level %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.Nodes %.v": "",
|
"cmd/compile/internal/gc.Nodes %.v": "",
|
||||||
|
|
@ -163,6 +161,7 @@ var knownFormats = map[string]string{
|
||||||
"int64 %v": "",
|
"int64 %v": "",
|
||||||
"int64 %x": "",
|
"int64 %x": "",
|
||||||
"int8 %d": "",
|
"int8 %d": "",
|
||||||
|
"int8 %v": "",
|
||||||
"int8 %x": "",
|
"int8 %x": "",
|
||||||
"interface{} %#v": "",
|
"interface{} %#v": "",
|
||||||
"interface{} %T": "",
|
"interface{} %T": "",
|
||||||
|
|
@ -173,6 +172,7 @@ var knownFormats = map[string]string{
|
||||||
"map[*cmd/compile/internal/gc.Node]*cmd/compile/internal/ssa.Value %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/gc.Node][]*cmd/compile/internal/gc.Node %v": "",
|
||||||
"map[cmd/compile/internal/ssa.ID]uint32 %v": "",
|
"map[cmd/compile/internal/ssa.ID]uint32 %v": "",
|
||||||
|
"map[int64]uint32 %v": "",
|
||||||
"math/big.Accuracy %s": "",
|
"math/big.Accuracy %s": "",
|
||||||
"reflect.Type %s": "",
|
"reflect.Type %s": "",
|
||||||
"rune %#U": "",
|
"rune %#U": "",
|
||||||
|
|
@ -181,7 +181,6 @@ var knownFormats = map[string]string{
|
||||||
"string %-*s": "",
|
"string %-*s": "",
|
||||||
"string %-16s": "",
|
"string %-16s": "",
|
||||||
"string %-6s": "",
|
"string %-6s": "",
|
||||||
"string %.*s": "",
|
|
||||||
"string %q": "",
|
"string %q": "",
|
||||||
"string %s": "",
|
"string %s": "",
|
||||||
"string %v": "",
|
"string %v": "",
|
||||||
|
|
@ -192,13 +191,14 @@ var knownFormats = map[string]string{
|
||||||
"uint %d": "",
|
"uint %d": "",
|
||||||
"uint %x": "",
|
"uint %x": "",
|
||||||
"uint16 %d": "",
|
"uint16 %d": "",
|
||||||
"uint16 %v": "",
|
|
||||||
"uint16 %x": "",
|
"uint16 %x": "",
|
||||||
|
"uint32 %#U": "",
|
||||||
"uint32 %#x": "",
|
"uint32 %#x": "",
|
||||||
"uint32 %d": "",
|
"uint32 %d": "",
|
||||||
"uint32 %v": "",
|
"uint32 %v": "",
|
||||||
"uint32 %x": "",
|
"uint32 %x": "",
|
||||||
"uint64 %08x": "",
|
"uint64 %08x": "",
|
||||||
|
"uint64 %b": "",
|
||||||
"uint64 %d": "",
|
"uint64 %d": "",
|
||||||
"uint64 %x": "",
|
"uint64 %x": "",
|
||||||
"uint8 %d": "",
|
"uint8 %d": "",
|
||||||
|
|
|
||||||
|
|
@ -7,22 +7,16 @@ package amd64
|
||||||
import (
|
import (
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
"cmd/internal/obj/x86"
|
"cmd/internal/obj/x86"
|
||||||
"cmd/internal/objabi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var leaptr = x86.ALEAQ
|
var leaptr = x86.ALEAQ
|
||||||
|
|
||||||
func Init(arch *gc.Arch) {
|
func Init(arch *gc.Arch) {
|
||||||
arch.LinkArch = &x86.Linkamd64
|
arch.LinkArch = &x86.Linkamd64
|
||||||
if objabi.GOARCH == "amd64p32" {
|
|
||||||
arch.LinkArch = &x86.Linkamd64p32
|
|
||||||
leaptr = x86.ALEAL
|
|
||||||
}
|
|
||||||
arch.REGSP = x86.REGSP
|
arch.REGSP = x86.REGSP
|
||||||
arch.MAXWIDTH = 1 << 50
|
arch.MAXWIDTH = 1 << 50
|
||||||
|
|
||||||
arch.ZeroRange = zerorange
|
arch.ZeroRange = zerorange
|
||||||
arch.ZeroAuto = zeroAuto
|
|
||||||
arch.Ginsnop = ginsnop
|
arch.Ginsnop = ginsnop
|
||||||
arch.Ginsnopdefer = ginsnop
|
arch.Ginsnopdefer = ginsnop
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Pr
|
||||||
if cnt%16 != 0 {
|
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.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_SP, off+cnt-int64(16))
|
||||||
}
|
}
|
||||||
} else if !gc.Nacl && !isPlan9 && (cnt <= int64(128*gc.Widthreg)) {
|
} else if !isPlan9 && (cnt <= int64(128*gc.Widthreg)) {
|
||||||
if *state&x0 == 0 {
|
if *state&x0 == 0 {
|
||||||
p = pp.Appendpp(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_REG, x86.REG_X0, 0)
|
p = pp.Appendpp(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_REG, x86.REG_X0, 0)
|
||||||
*state |= x0
|
*state |= x0
|
||||||
|
|
@ -121,26 +121,6 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Pr
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func zeroAuto(pp *gc.Progs, n *gc.Node) {
|
|
||||||
// Note: this code must not clobber any registers.
|
|
||||||
op := x86.AMOVQ
|
|
||||||
if gc.Widthptr == 4 {
|
|
||||||
op = x86.AMOVL
|
|
||||||
}
|
|
||||||
sym := n.Sym.Linksym()
|
|
||||||
size := n.Type.Size()
|
|
||||||
for i := int64(0); i < size; i += int64(gc.Widthptr) {
|
|
||||||
p := pp.Prog(op)
|
|
||||||
p.From.Type = obj.TYPE_CONST
|
|
||||||
p.From.Offset = 0
|
|
||||||
p.To.Type = obj.TYPE_MEM
|
|
||||||
p.To.Name = obj.NAME_AUTO
|
|
||||||
p.To.Reg = x86.REG_SP
|
|
||||||
p.To.Offset = n.Xoffset + i
|
|
||||||
p.To.Sym = sym
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ginsnop(pp *gc.Progs) *obj.Prog {
|
func ginsnop(pp *gc.Progs) *obj.Prog {
|
||||||
// This is a hardware nop (1-byte 0x90) instruction,
|
// This is a hardware nop (1-byte 0x90) instruction,
|
||||||
// even though we describe it as an explicit XCHGL here.
|
// even though we describe it as an explicit XCHGL here.
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
|
"cmd/compile/internal/logopt"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
|
|
@ -18,8 +19,8 @@ import (
|
||||||
// markMoves marks any MOVXconst ops that need to avoid clobbering flags.
|
// markMoves marks any MOVXconst ops that need to avoid clobbering flags.
|
||||||
func ssaMarkMoves(s *gc.SSAGenState, b *ssa.Block) {
|
func ssaMarkMoves(s *gc.SSAGenState, b *ssa.Block) {
|
||||||
flive := b.FlagsLiveAtEnd
|
flive := b.FlagsLiveAtEnd
|
||||||
if b.Control != nil && b.Control.Type.IsFlags() {
|
for _, c := range b.ControlValues() {
|
||||||
flive = true
|
flive = c.Type.IsFlags() || flive
|
||||||
}
|
}
|
||||||
for i := len(b.Values) - 1; i >= 0; i-- {
|
for i := len(b.Values) - 1; i >= 0; i-- {
|
||||||
v := b.Values[i]
|
v := b.Values[i]
|
||||||
|
|
@ -164,6 +165,14 @@ func duff(size int64) (int64, int64) {
|
||||||
|
|
||||||
func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
switch v.Op {
|
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())
|
||||||
|
}
|
||||||
case ssa.OpAMD64ADDQ, ssa.OpAMD64ADDL:
|
case ssa.OpAMD64ADDQ, ssa.OpAMD64ADDL:
|
||||||
r := v.Reg()
|
r := v.Reg()
|
||||||
r1 := v.Args[0].Reg()
|
r1 := v.Args[0].Reg()
|
||||||
|
|
@ -947,13 +956,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
|
p.To.Sym = gc.BoundsCheckFunc[v.AuxInt]
|
||||||
s.UseArgs(int64(2 * gc.Widthptr)) // space used in callee args area by assembly stubs
|
s.UseArgs(int64(2 * gc.Widthptr)) // space used in callee args area by assembly stubs
|
||||||
|
|
||||||
case ssa.OpAMD64LoweredPanicExtendA, ssa.OpAMD64LoweredPanicExtendB, ssa.OpAMD64LoweredPanicExtendC:
|
|
||||||
p := s.Prog(obj.ACALL)
|
|
||||||
p.To.Type = obj.TYPE_MEM
|
|
||||||
p.To.Name = obj.NAME_EXTERN
|
|
||||||
p.To.Sym = gc.ExtendCheckFunc[v.AuxInt]
|
|
||||||
s.UseArgs(int64(3 * gc.Widthptr)) // space used in callee args area by assembly stubs
|
|
||||||
|
|
||||||
case ssa.OpAMD64NEGQ, ssa.OpAMD64NEGL,
|
case ssa.OpAMD64NEGQ, ssa.OpAMD64NEGL,
|
||||||
ssa.OpAMD64BSWAPQ, ssa.OpAMD64BSWAPL,
|
ssa.OpAMD64BSWAPQ, ssa.OpAMD64BSWAPL,
|
||||||
ssa.OpAMD64NOTQ, ssa.OpAMD64NOTL:
|
ssa.OpAMD64NOTQ, ssa.OpAMD64NOTL:
|
||||||
|
|
@ -1080,6 +1082,9 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
p.To.Type = obj.TYPE_MEM
|
p.To.Type = obj.TYPE_MEM
|
||||||
p.To.Reg = v.Args[0].Reg()
|
p.To.Reg = v.Args[0].Reg()
|
||||||
gc.AddAux(&p.To, v)
|
gc.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
|
if gc.Debug_checknil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
||||||
gc.Warnl(v.Pos, "generated nil check")
|
gc.Warnl(v.Pos, "generated nil check")
|
||||||
}
|
}
|
||||||
|
|
@ -1090,7 +1095,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
gc.AddAux(&p.From, v)
|
gc.AddAux(&p.From, v)
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = v.Reg0()
|
p.To.Reg = v.Reg0()
|
||||||
case ssa.OpAMD64XCHGL, ssa.OpAMD64XCHGQ:
|
case ssa.OpAMD64XCHGB, ssa.OpAMD64XCHGL, ssa.OpAMD64XCHGQ:
|
||||||
r := v.Reg0()
|
r := v.Reg0()
|
||||||
if r != v.Args[0].Reg() {
|
if r != v.Args[0].Reg() {
|
||||||
v.Fatalf("input[0] and output[0] not in same register %s", v.LongString())
|
v.Fatalf("input[0] and output[0] not in same register %s", v.LongString())
|
||||||
|
|
@ -1245,6 +1250,6 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
b.Fatalf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
b.Fatalf("branch not implemented: %s", b.LongString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ func Init(arch *gc.Arch) {
|
||||||
arch.MAXWIDTH = (1 << 32) - 1
|
arch.MAXWIDTH = (1 << 32) - 1
|
||||||
arch.SoftFloat = objabi.GOARM == 5
|
arch.SoftFloat = objabi.GOARM == 5
|
||||||
arch.ZeroRange = zerorange
|
arch.ZeroRange = zerorange
|
||||||
arch.ZeroAuto = zeroAuto
|
|
||||||
arch.Ginsnop = ginsnop
|
arch.Ginsnop = ginsnop
|
||||||
arch.Ginsnopdefer = ginsnop
|
arch.Ginsnopdefer = ginsnop
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, r0 *uint32) *obj.Prog
|
||||||
for i := int64(0); i < cnt; i += int64(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)
|
p = pp.Appendpp(p, arm.AMOVW, obj.TYPE_REG, arm.REG_R0, 0, obj.TYPE_MEM, arm.REGSP, 4+off+i)
|
||||||
}
|
}
|
||||||
} else if !gc.Nacl && (cnt <= int64(128*gc.Widthptr)) {
|
} 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)
|
p = pp.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0, 4+off, obj.TYPE_REG, arm.REG_R1, 0)
|
||||||
p.Reg = arm.REGSP
|
p.Reg = arm.REGSP
|
||||||
p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
|
p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
|
||||||
|
|
@ -47,27 +47,6 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, r0 *uint32) *obj.Prog
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func zeroAuto(pp *gc.Progs, n *gc.Node) {
|
|
||||||
// Note: this code must not clobber any registers.
|
|
||||||
sym := n.Sym.Linksym()
|
|
||||||
size := n.Type.Size()
|
|
||||||
p := pp.Prog(arm.AMOVW)
|
|
||||||
p.From.Type = obj.TYPE_CONST
|
|
||||||
p.From.Offset = 0
|
|
||||||
p.To.Type = obj.TYPE_REG
|
|
||||||
p.To.Reg = arm.REGTMP
|
|
||||||
for i := int64(0); i < size; i += 4 {
|
|
||||||
p := pp.Prog(arm.AMOVW)
|
|
||||||
p.From.Type = obj.TYPE_REG
|
|
||||||
p.From.Reg = arm.REGTMP
|
|
||||||
p.To.Type = obj.TYPE_MEM
|
|
||||||
p.To.Name = obj.NAME_AUTO
|
|
||||||
p.To.Reg = arm.REGSP
|
|
||||||
p.To.Offset = n.Xoffset + i
|
|
||||||
p.To.Sym = sym
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ginsnop(pp *gc.Progs) *obj.Prog {
|
func ginsnop(pp *gc.Progs) *obj.Prog {
|
||||||
p := pp.Prog(arm.AAND)
|
p := pp.Prog(arm.AAND)
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"math/bits"
|
"math/bits"
|
||||||
|
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
|
"cmd/compile/internal/logopt"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
|
|
@ -224,7 +225,9 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
p.Reg = r1
|
p.Reg = r1
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = r
|
p.To.Reg = r
|
||||||
case ssa.OpARMMULAF, ssa.OpARMMULAD, ssa.OpARMMULSF, ssa.OpARMMULSD:
|
case ssa.OpARMSRR:
|
||||||
|
genregshift(s, arm.AMOVW, 0, v.Args[0].Reg(), v.Args[1].Reg(), v.Reg(), arm.SHIFT_RR)
|
||||||
|
case ssa.OpARMMULAF, ssa.OpARMMULAD, ssa.OpARMMULSF, ssa.OpARMMULSD, ssa.OpARMFMULAD:
|
||||||
r := v.Reg()
|
r := v.Reg()
|
||||||
r0 := v.Args[0].Reg()
|
r0 := v.Args[0].Reg()
|
||||||
r1 := v.Args[1].Reg()
|
r1 := v.Args[1].Reg()
|
||||||
|
|
@ -655,6 +658,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
ssa.OpARMSQRTD,
|
ssa.OpARMSQRTD,
|
||||||
ssa.OpARMNEGF,
|
ssa.OpARMNEGF,
|
||||||
ssa.OpARMNEGD,
|
ssa.OpARMNEGD,
|
||||||
|
ssa.OpARMABSD,
|
||||||
ssa.OpARMMOVWF,
|
ssa.OpARMMOVWF,
|
||||||
ssa.OpARMMOVWD,
|
ssa.OpARMMOVWD,
|
||||||
ssa.OpARMMOVFW,
|
ssa.OpARMMOVFW,
|
||||||
|
|
@ -734,6 +738,9 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
gc.AddAux(&p.From, v)
|
gc.AddAux(&p.From, v)
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = arm.REGTMP
|
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
|
if gc.Debug_checknil != 0 && v.Pos.Line() > 1 { // v.Pos.Line()==1 in generated wrappers
|
||||||
gc.Warnl(v.Pos, "generated nil check")
|
gc.Warnl(v.Pos, "generated nil check")
|
||||||
}
|
}
|
||||||
|
|
@ -952,6 +959,6 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
b.Fatalf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
b.Fatalf("branch not implemented: %s", b.LongString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ func Init(arch *gc.Arch) {
|
||||||
|
|
||||||
arch.PadFrame = padframe
|
arch.PadFrame = padframe
|
||||||
arch.ZeroRange = zerorange
|
arch.ZeroRange = zerorange
|
||||||
arch.ZeroAuto = zeroAuto
|
|
||||||
arch.Ginsnop = ginsnop
|
arch.Ginsnop = ginsnop
|
||||||
arch.Ginsnopdefer = ginsnop
|
arch.Ginsnopdefer = ginsnop
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,12 +44,16 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
|
||||||
p.To.Sym = gc.Duffzero
|
p.To.Sym = gc.Duffzero
|
||||||
p.To.Offset = 4 * (64 - cnt/(2*int64(gc.Widthptr)))
|
p.To.Offset = 4 * (64 - cnt/(2*int64(gc.Widthptr)))
|
||||||
} else {
|
} else {
|
||||||
p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, arm64.REGTMP, 0)
|
// 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.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REGRT1, 0)
|
||||||
p = pp.Appendpp(p, arm64.AADD, obj.TYPE_REG, arm64.REGTMP, 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.Reg = arm64.REGRT1
|
p.Reg = arm64.REGRT1
|
||||||
p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, arm64.REGTMP, 0)
|
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, arm64.REGTMP, 0, obj.TYPE_REG, arm64.REGRT2, 0)
|
p = pp.Appendpp(p, arm64.AADD, obj.TYPE_REG, rtmp, 0, obj.TYPE_REG, arm64.REGRT2, 0)
|
||||||
p.Reg = arm64.REGRT1
|
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.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGRT1, int64(gc.Widthptr))
|
||||||
p.Scond = arm64.C_XPRE
|
p.Scond = arm64.C_XPRE
|
||||||
|
|
@ -63,22 +67,6 @@ func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func zeroAuto(pp *gc.Progs, n *gc.Node) {
|
|
||||||
// Note: this code must not clobber any registers.
|
|
||||||
sym := n.Sym.Linksym()
|
|
||||||
size := n.Type.Size()
|
|
||||||
for i := int64(0); i < size; i += 8 {
|
|
||||||
p := pp.Prog(arm64.AMOVD)
|
|
||||||
p.From.Type = obj.TYPE_REG
|
|
||||||
p.From.Reg = arm64.REGZERO
|
|
||||||
p.To.Type = obj.TYPE_MEM
|
|
||||||
p.To.Name = obj.NAME_AUTO
|
|
||||||
p.To.Reg = arm64.REGSP
|
|
||||||
p.To.Offset = n.Xoffset + i
|
|
||||||
p.To.Sym = sym
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ginsnop(pp *gc.Progs) *obj.Prog {
|
func ginsnop(pp *gc.Progs) *obj.Prog {
|
||||||
p := pp.Prog(arm64.AHINT)
|
p := pp.Prog(arm64.AHINT)
|
||||||
p.From.Type = obj.TYPE_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"cmd/compile/internal/gc"
|
"cmd/compile/internal/gc"
|
||||||
|
"cmd/compile/internal/logopt"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
|
|
@ -452,6 +453,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
ssa.OpARM64MOVDstore,
|
ssa.OpARM64MOVDstore,
|
||||||
ssa.OpARM64FMOVSstore,
|
ssa.OpARM64FMOVSstore,
|
||||||
ssa.OpARM64FMOVDstore,
|
ssa.OpARM64FMOVDstore,
|
||||||
|
ssa.OpARM64STLRB,
|
||||||
ssa.OpARM64STLR,
|
ssa.OpARM64STLR,
|
||||||
ssa.OpARM64STLRW:
|
ssa.OpARM64STLRW:
|
||||||
p := s.Prog(v.Op.Asm())
|
p := s.Prog(v.Op.Asm())
|
||||||
|
|
@ -900,6 +902,9 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
gc.AddAux(&p.From, v)
|
gc.AddAux(&p.From, v)
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = arm64.REGTMP
|
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
|
if gc.Debug_checknil != 0 && v.Pos.Line() > 1 { // v.Line==1 in generated wrappers
|
||||||
gc.Warnl(v.Pos, "generated nil check")
|
gc.Warnl(v.Pos, "generated nil check")
|
||||||
}
|
}
|
||||||
|
|
@ -1057,9 +1062,9 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
||||||
s.Br(obj.AJMP, b.Succs[0].Block())
|
s.Br(obj.AJMP, b.Succs[0].Block())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !b.Control.Type.IsFlags() {
|
if !b.Controls[0].Type.IsFlags() {
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = b.Control.Reg()
|
p.From.Reg = b.Controls[0].Reg()
|
||||||
}
|
}
|
||||||
case ssa.BlockARM64TBZ, ssa.BlockARM64TBNZ:
|
case ssa.BlockARM64TBZ, ssa.BlockARM64TBNZ:
|
||||||
jmp := blockJump[b.Kind]
|
jmp := blockJump[b.Kind]
|
||||||
|
|
@ -1080,9 +1085,9 @@ func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
|
||||||
}
|
}
|
||||||
p.From.Offset = b.Aux.(int64)
|
p.From.Offset = b.Aux.(int64)
|
||||||
p.From.Type = obj.TYPE_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.Reg = b.Control.Reg()
|
p.Reg = b.Controls[0].Reg()
|
||||||
|
|
||||||
default:
|
default:
|
||||||
b.Fatalf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
|
b.Fatalf("branch not implemented: %s", b.LongString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
|
"cmd/internal/obj"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -183,10 +184,82 @@ func algtype1(t *types.Type) (AlgKind, *types.Type) {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a helper function to compute the hash of a value of type t.
|
// genhash returns a symbol which is the closure used to compute
|
||||||
func genhash(sym *types.Sym, t *types.Type) {
|
// the hash of a value of type t.
|
||||||
|
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 {
|
if Debug['r'] != 0 {
|
||||||
fmt.Printf("genhash %v %v\n", sym, t)
|
fmt.Printf("genhash %v %v %v\n", closure, sym, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
lineno = autogeneratedPos // less confusing than end of input
|
lineno = autogeneratedPos // less confusing than end of input
|
||||||
|
|
@ -204,13 +277,7 @@ func genhash(sym *types.Sym, t *types.Type) {
|
||||||
np := asNode(tfn.Type.Params().Field(0).Nname)
|
np := asNode(tfn.Type.Params().Field(0).Nname)
|
||||||
nh := asNode(tfn.Type.Params().Field(1).Nname)
|
nh := asNode(tfn.Type.Params().Field(1).Nname)
|
||||||
|
|
||||||
// genhash is only called 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 {
|
switch t.Etype {
|
||||||
default:
|
|
||||||
Fatalf("genhash %v", t)
|
|
||||||
|
|
||||||
case types.TARRAY:
|
case types.TARRAY:
|
||||||
// An array of pure memory would be handled by the
|
// An array of pure memory would be handled by the
|
||||||
// standard algorithm, so the element type must not be
|
// standard algorithm, so the element type must not be
|
||||||
|
|
@ -302,6 +369,13 @@ func genhash(sym *types.Sym, t *types.Type) {
|
||||||
|
|
||||||
fn.Func.SetNilCheckDisabled(true)
|
fn.Func.SetNilCheckDisabled(true)
|
||||||
funccompile(fn)
|
funccompile(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 {
|
func hashfor(t *types.Type) *Node {
|
||||||
|
|
@ -325,6 +399,8 @@ func hashfor(t *types.Type) *Node {
|
||||||
case ACPLX128:
|
case ACPLX128:
|
||||||
sym = Runtimepkg.Lookup("c128hash")
|
sym = Runtimepkg.Lookup("c128hash")
|
||||||
default:
|
default:
|
||||||
|
// Note: the caller of hashfor ensured that this symbol
|
||||||
|
// exists and has a body by calling genhash for t.
|
||||||
sym = typesymprefix(".hash", t)
|
sym = typesymprefix(".hash", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -340,12 +416,81 @@ func hashfor(t *types.Type) *Node {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// geneq generates a helper function to
|
// sysClosure returns a closure which will call the
|
||||||
// check equality of two values of type t.
|
// given runtime function (with no closed-over variables).
|
||||||
func geneq(sym *types.Sym, t *types.Type) {
|
func sysClosure(name string) *obj.LSym {
|
||||||
if Debug['r'] != 0 {
|
s := sysvar(name + "·f")
|
||||||
fmt.Printf("geneq %v %v\n", sym, t)
|
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
|
lineno = autogeneratedPos // less confusing than end of input
|
||||||
dclcontext = PEXTERN
|
dclcontext = PEXTERN
|
||||||
|
|
@ -362,7 +507,7 @@ func geneq(sym *types.Sym, t *types.Type) {
|
||||||
np := asNode(tfn.Type.Params().Field(0).Nname)
|
np := asNode(tfn.Type.Params().Field(0).Nname)
|
||||||
nq := asNode(tfn.Type.Params().Field(1).Nname)
|
nq := asNode(tfn.Type.Params().Field(1).Nname)
|
||||||
|
|
||||||
// geneq is only called for types that have equality but
|
// We reach here only for types that have equality but
|
||||||
// cannot be handled by the standard algorithms,
|
// cannot be handled by the standard algorithms,
|
||||||
// so t must be either an array or a struct.
|
// so t must be either an array or a struct.
|
||||||
switch t.Etype {
|
switch t.Etype {
|
||||||
|
|
@ -481,6 +626,11 @@ func geneq(sym *types.Sym, t *types.Type) {
|
||||||
// are shallow.
|
// are shallow.
|
||||||
fn.Func.SetNilCheckDisabled(true)
|
fn.Func.SetNilCheckDisabled(true)
|
||||||
funccompile(fn)
|
funccompile(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
|
||||||
}
|
}
|
||||||
|
|
||||||
// eqfield returns the node
|
// eqfield returns the node
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ func expandiface(t *types.Type) {
|
||||||
switch prev := seen[m.Sym]; {
|
switch prev := seen[m.Sym]; {
|
||||||
case prev == nil:
|
case prev == nil:
|
||||||
seen[m.Sym] = m
|
seen[m.Sym] = m
|
||||||
case !explicit && types.Identical(m.Type, prev.Type):
|
case langSupported(1, 14, t.Pkg()) && !explicit && types.Identical(m.Type, prev.Type):
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
yyerrorl(m.Pos, "duplicate method %s", m.Sym.Name)
|
yyerrorl(m.Pos, "duplicate method %s", m.Sym.Name)
|
||||||
|
|
@ -178,6 +178,11 @@ func widstruct(errtype *types.Type, t *types.Type, o int64, flag int) int64 {
|
||||||
// have not already been calculated, it calls Fatal.
|
// have not already been calculated, it calls Fatal.
|
||||||
// This is used to prevent data races in the back end.
|
// This is used to prevent data races in the back end.
|
||||||
func dowidth(t *types.Type) {
|
func dowidth(t *types.Type) {
|
||||||
|
// Calling dowidth when typecheck tracing enabled is not safe.
|
||||||
|
// See issue #33658.
|
||||||
|
if enableTrace && skipDowidthForTracing {
|
||||||
|
return
|
||||||
|
}
|
||||||
if Widthptr == 0 {
|
if Widthptr == 0 {
|
||||||
Fatalf("dowidth without betypeinit")
|
Fatalf("dowidth without betypeinit")
|
||||||
}
|
}
|
||||||
|
|
@ -189,16 +194,7 @@ func dowidth(t *types.Type) {
|
||||||
if t.Width == -2 {
|
if t.Width == -2 {
|
||||||
if !t.Broke() {
|
if !t.Broke() {
|
||||||
t.SetBroke(true)
|
t.SetBroke(true)
|
||||||
// t.Nod should not be nil here, but in some cases is appears to be
|
yyerrorl(asNode(t.Nod).Pos, "invalid recursive type %v", t)
|
||||||
// (see issue #23823). For now (temporary work-around) at a minimum
|
|
||||||
// don't crash and provide a meaningful error message.
|
|
||||||
// TODO(gri) determine the correct fix during a regular devel cycle
|
|
||||||
// (see issue #31872).
|
|
||||||
if t.Nod == nil {
|
|
||||||
yyerror("invalid recursive type %v", t)
|
|
||||||
} else {
|
|
||||||
yyerrorl(asNode(t.Nod).Pos, "invalid recursive type %v", t)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Width = 0
|
t.Width = 0
|
||||||
|
|
@ -226,7 +222,7 @@ func dowidth(t *types.Type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// defer checkwidth calls until after we're done
|
// defer checkwidth calls until after we're done
|
||||||
defercalc++
|
defercheckwidth()
|
||||||
|
|
||||||
lno := lineno
|
lno := lineno
|
||||||
if asNode(t.Nod) != nil {
|
if asNode(t.Nod) != nil {
|
||||||
|
|
@ -333,13 +329,6 @@ func dowidth(t *types.Type) {
|
||||||
if t.Elem() == nil {
|
if t.Elem() == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if t.IsDDDArray() {
|
|
||||||
if !t.Broke() {
|
|
||||||
yyerror("use of [...] array outside of array literal")
|
|
||||||
t.SetBroke(true)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
dowidth(t.Elem())
|
dowidth(t.Elem())
|
||||||
if t.Elem().Width != 0 {
|
if t.Elem().Width != 0 {
|
||||||
|
|
@ -355,7 +344,7 @@ func dowidth(t *types.Type) {
|
||||||
if t.Elem() == nil {
|
if t.Elem() == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
w = int64(sizeof_Array)
|
w = int64(sizeof_Slice)
|
||||||
checkwidth(t.Elem())
|
checkwidth(t.Elem())
|
||||||
t.Align = uint8(Widthptr)
|
t.Align = uint8(Widthptr)
|
||||||
|
|
||||||
|
|
@ -400,11 +389,7 @@ func dowidth(t *types.Type) {
|
||||||
|
|
||||||
lineno = lno
|
lineno = lno
|
||||||
|
|
||||||
if defercalc == 1 {
|
resumecheckwidth()
|
||||||
resumecheckwidth()
|
|
||||||
} else {
|
|
||||||
defercalc--
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// when a type's width should be known, we call checkwidth
|
// when a type's width should be known, we call checkwidth
|
||||||
|
|
@ -449,24 +434,18 @@ func checkwidth(t *types.Type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func defercheckwidth() {
|
func defercheckwidth() {
|
||||||
// we get out of sync on syntax errors, so don't be pedantic.
|
defercalc++
|
||||||
if defercalc != 0 && nerrors == 0 {
|
|
||||||
Fatalf("defercheckwidth")
|
|
||||||
}
|
|
||||||
defercalc = 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func resumecheckwidth() {
|
func resumecheckwidth() {
|
||||||
if defercalc == 0 {
|
if defercalc == 1 {
|
||||||
Fatalf("resumecheckwidth")
|
for len(deferredTypeStack) > 0 {
|
||||||
|
t := deferredTypeStack[len(deferredTypeStack)-1]
|
||||||
|
deferredTypeStack = deferredTypeStack[:len(deferredTypeStack)-1]
|
||||||
|
t.SetDeferwidth(false)
|
||||||
|
dowidth(t)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for len(deferredTypeStack) > 0 {
|
defercalc--
|
||||||
t := deferredTypeStack[len(deferredTypeStack)-1]
|
|
||||||
deferredTypeStack = deferredTypeStack[:len(deferredTypeStack)-1]
|
|
||||||
t.SetDeferwidth(false)
|
|
||||||
dowidth(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
defercalc = 0
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,14 @@ func (p *exporter) markType(t *types.Type) {
|
||||||
// the user already needs some way to construct values of
|
// the user already needs some way to construct values of
|
||||||
// those types.
|
// those types.
|
||||||
switch t.Etype {
|
switch t.Etype {
|
||||||
case TPTR, TARRAY, TSLICE, TCHAN:
|
case TPTR, TARRAY, TSLICE:
|
||||||
// TODO(mdempsky): Skip marking element type for
|
|
||||||
// send-only channels?
|
|
||||||
p.markType(t.Elem())
|
p.markType(t.Elem())
|
||||||
|
|
||||||
|
case TCHAN:
|
||||||
|
if t.ChanDir().CanRecv() {
|
||||||
|
p.markType(t.Elem())
|
||||||
|
}
|
||||||
|
|
||||||
case TMAP:
|
case TMAP:
|
||||||
p.markType(t.Key())
|
p.markType(t.Key())
|
||||||
p.markType(t.Elem())
|
p.markType(t.Elem())
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/compile/internal/types"
|
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -15,15 +14,6 @@ import (
|
||||||
// the same name appears in an error message.
|
// the same name appears in an error message.
|
||||||
var numImport = make(map[string]int)
|
var numImport = make(map[string]int)
|
||||||
|
|
||||||
func idealType(typ *types.Type) *types.Type {
|
|
||||||
switch typ {
|
|
||||||
case types.Idealint, types.Idealrune, types.Idealfloat, types.Idealcomplex:
|
|
||||||
// canonicalize ideal types
|
|
||||||
typ = types.Types[TIDEAL]
|
|
||||||
}
|
|
||||||
return typ
|
|
||||||
}
|
|
||||||
|
|
||||||
func npos(pos src.XPos, n *Node) *Node {
|
func npos(pos src.XPos, n *Node) *Node {
|
||||||
n.Pos = pos
|
n.Pos = pos
|
||||||
return n
|
return n
|
||||||
|
|
|
||||||
|
|
@ -134,38 +134,72 @@ var runtimeDecls = [...]struct {
|
||||||
{"memclrNoHeapPointers", funcTag, 103},
|
{"memclrNoHeapPointers", funcTag, 103},
|
||||||
{"memclrHasPointers", funcTag, 103},
|
{"memclrHasPointers", funcTag, 103},
|
||||||
{"memequal", funcTag, 104},
|
{"memequal", funcTag, 104},
|
||||||
|
{"memequal0", funcTag, 105},
|
||||||
{"memequal8", funcTag, 105},
|
{"memequal8", funcTag, 105},
|
||||||
{"memequal16", funcTag, 105},
|
{"memequal16", funcTag, 105},
|
||||||
{"memequal32", funcTag, 105},
|
{"memequal32", funcTag, 105},
|
||||||
{"memequal64", funcTag, 105},
|
{"memequal64", funcTag, 105},
|
||||||
{"memequal128", funcTag, 105},
|
{"memequal128", funcTag, 105},
|
||||||
{"int64div", funcTag, 106},
|
{"f32equal", funcTag, 106},
|
||||||
{"uint64div", funcTag, 107},
|
{"f64equal", funcTag, 106},
|
||||||
{"int64mod", funcTag, 106},
|
{"c64equal", funcTag, 106},
|
||||||
{"uint64mod", funcTag, 107},
|
{"c128equal", funcTag, 106},
|
||||||
{"float64toint64", funcTag, 108},
|
{"strequal", funcTag, 106},
|
||||||
{"float64touint64", funcTag, 109},
|
{"interequal", funcTag, 106},
|
||||||
{"float64touint32", funcTag, 110},
|
{"nilinterequal", funcTag, 106},
|
||||||
{"int64tofloat64", funcTag, 111},
|
{"memhash", funcTag, 107},
|
||||||
{"uint64tofloat64", funcTag, 112},
|
{"memhash0", funcTag, 108},
|
||||||
{"uint32tofloat64", funcTag, 113},
|
{"memhash8", funcTag, 108},
|
||||||
{"complex128div", funcTag, 114},
|
{"memhash16", funcTag, 108},
|
||||||
{"racefuncenter", funcTag, 115},
|
{"memhash32", funcTag, 108},
|
||||||
|
{"memhash64", funcTag, 108},
|
||||||
|
{"memhash128", funcTag, 108},
|
||||||
|
{"f32hash", funcTag, 108},
|
||||||
|
{"f64hash", funcTag, 108},
|
||||||
|
{"c64hash", funcTag, 108},
|
||||||
|
{"c128hash", funcTag, 108},
|
||||||
|
{"strhash", funcTag, 108},
|
||||||
|
{"interhash", funcTag, 108},
|
||||||
|
{"nilinterhash", funcTag, 108},
|
||||||
|
{"int64div", funcTag, 109},
|
||||||
|
{"uint64div", funcTag, 110},
|
||||||
|
{"int64mod", funcTag, 109},
|
||||||
|
{"uint64mod", funcTag, 110},
|
||||||
|
{"float64toint64", funcTag, 111},
|
||||||
|
{"float64touint64", funcTag, 112},
|
||||||
|
{"float64touint32", funcTag, 113},
|
||||||
|
{"int64tofloat64", funcTag, 114},
|
||||||
|
{"uint64tofloat64", funcTag, 115},
|
||||||
|
{"uint32tofloat64", funcTag, 116},
|
||||||
|
{"complex128div", funcTag, 117},
|
||||||
|
{"racefuncenter", funcTag, 118},
|
||||||
{"racefuncenterfp", funcTag, 5},
|
{"racefuncenterfp", funcTag, 5},
|
||||||
{"racefuncexit", funcTag, 5},
|
{"racefuncexit", funcTag, 5},
|
||||||
{"raceread", funcTag, 115},
|
{"raceread", funcTag, 118},
|
||||||
{"racewrite", funcTag, 115},
|
{"racewrite", funcTag, 118},
|
||||||
{"racereadrange", funcTag, 116},
|
{"racereadrange", funcTag, 119},
|
||||||
{"racewriterange", funcTag, 116},
|
{"racewriterange", funcTag, 119},
|
||||||
{"msanread", funcTag, 116},
|
{"msanread", funcTag, 119},
|
||||||
{"msanwrite", funcTag, 116},
|
{"msanwrite", funcTag, 119},
|
||||||
|
{"checkptrAlignment", funcTag, 120},
|
||||||
|
{"checkptrArithmetic", funcTag, 122},
|
||||||
|
{"libfuzzerTraceCmp1", funcTag, 124},
|
||||||
|
{"libfuzzerTraceCmp2", funcTag, 126},
|
||||||
|
{"libfuzzerTraceCmp4", funcTag, 127},
|
||||||
|
{"libfuzzerTraceCmp8", funcTag, 128},
|
||||||
|
{"libfuzzerTraceConstCmp1", funcTag, 124},
|
||||||
|
{"libfuzzerTraceConstCmp2", funcTag, 126},
|
||||||
|
{"libfuzzerTraceConstCmp4", funcTag, 127},
|
||||||
|
{"libfuzzerTraceConstCmp8", funcTag, 128},
|
||||||
{"x86HasPOPCNT", varTag, 15},
|
{"x86HasPOPCNT", varTag, 15},
|
||||||
{"x86HasSSE41", varTag, 15},
|
{"x86HasSSE41", varTag, 15},
|
||||||
|
{"x86HasFMA", varTag, 15},
|
||||||
|
{"armHasVFPv4", varTag, 15},
|
||||||
{"arm64HasATOMICS", varTag, 15},
|
{"arm64HasATOMICS", varTag, 15},
|
||||||
}
|
}
|
||||||
|
|
||||||
func runtimeTypes() []*types.Type {
|
func runtimeTypes() []*types.Type {
|
||||||
var typs [117]*types.Type
|
var typs [129]*types.Type
|
||||||
typs[0] = types.Bytetype
|
typs[0] = types.Bytetype
|
||||||
typs[1] = types.NewPtr(typs[0])
|
typs[1] = types.NewPtr(typs[0])
|
||||||
typs[2] = types.Types[TANY]
|
typs[2] = types.Types[TANY]
|
||||||
|
|
@ -272,16 +306,28 @@ func runtimeTypes() []*types.Type {
|
||||||
typs[103] = functype(nil, []*Node{anonfield(typs[56]), anonfield(typs[50])}, nil)
|
typs[103] = functype(nil, []*Node{anonfield(typs[56]), anonfield(typs[50])}, nil)
|
||||||
typs[104] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[50])}, []*Node{anonfield(typs[15])})
|
typs[104] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[50])}, []*Node{anonfield(typs[15])})
|
||||||
typs[105] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[15])})
|
typs[105] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[15])})
|
||||||
typs[106] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
|
typs[106] = functype(nil, []*Node{anonfield(typs[56]), anonfield(typs[56])}, []*Node{anonfield(typs[15])})
|
||||||
typs[107] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
|
typs[107] = functype(nil, []*Node{anonfield(typs[56]), anonfield(typs[50]), anonfield(typs[50])}, []*Node{anonfield(typs[50])})
|
||||||
typs[108] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[19])})
|
typs[108] = functype(nil, []*Node{anonfield(typs[56]), anonfield(typs[50])}, []*Node{anonfield(typs[50])})
|
||||||
typs[109] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[21])})
|
typs[109] = functype(nil, []*Node{anonfield(typs[19]), anonfield(typs[19])}, []*Node{anonfield(typs[19])})
|
||||||
typs[110] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[64])})
|
typs[110] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, []*Node{anonfield(typs[21])})
|
||||||
typs[111] = functype(nil, []*Node{anonfield(typs[19])}, []*Node{anonfield(typs[17])})
|
typs[111] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[19])})
|
||||||
typs[112] = functype(nil, []*Node{anonfield(typs[21])}, []*Node{anonfield(typs[17])})
|
typs[112] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[21])})
|
||||||
typs[113] = functype(nil, []*Node{anonfield(typs[64])}, []*Node{anonfield(typs[17])})
|
typs[113] = functype(nil, []*Node{anonfield(typs[17])}, []*Node{anonfield(typs[64])})
|
||||||
typs[114] = functype(nil, []*Node{anonfield(typs[23]), anonfield(typs[23])}, []*Node{anonfield(typs[23])})
|
typs[114] = functype(nil, []*Node{anonfield(typs[19])}, []*Node{anonfield(typs[17])})
|
||||||
typs[115] = functype(nil, []*Node{anonfield(typs[50])}, nil)
|
typs[115] = functype(nil, []*Node{anonfield(typs[21])}, []*Node{anonfield(typs[17])})
|
||||||
typs[116] = functype(nil, []*Node{anonfield(typs[50]), anonfield(typs[50])}, nil)
|
typs[116] = functype(nil, []*Node{anonfield(typs[64])}, []*Node{anonfield(typs[17])})
|
||||||
|
typs[117] = functype(nil, []*Node{anonfield(typs[23]), anonfield(typs[23])}, []*Node{anonfield(typs[23])})
|
||||||
|
typs[118] = functype(nil, []*Node{anonfield(typs[50])}, nil)
|
||||||
|
typs[119] = functype(nil, []*Node{anonfield(typs[50]), anonfield(typs[50])}, nil)
|
||||||
|
typs[120] = functype(nil, []*Node{anonfield(typs[56]), anonfield(typs[1]), anonfield(typs[50])}, nil)
|
||||||
|
typs[121] = types.NewSlice(typs[56])
|
||||||
|
typs[122] = functype(nil, []*Node{anonfield(typs[56]), anonfield(typs[121])}, nil)
|
||||||
|
typs[123] = types.Types[TUINT8]
|
||||||
|
typs[124] = functype(nil, []*Node{anonfield(typs[123]), anonfield(typs[123])}, nil)
|
||||||
|
typs[125] = types.Types[TUINT16]
|
||||||
|
typs[126] = functype(nil, []*Node{anonfield(typs[125]), anonfield(typs[125])}, nil)
|
||||||
|
typs[127] = functype(nil, []*Node{anonfield(typs[64]), anonfield(typs[64])}, nil)
|
||||||
|
typs[128] = functype(nil, []*Node{anonfield(typs[21]), anonfield(typs[21])}, nil)
|
||||||
return typs[:]
|
return typs[:]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -179,11 +179,34 @@ func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
|
||||||
func memclrHasPointers(ptr unsafe.Pointer, n uintptr)
|
func memclrHasPointers(ptr unsafe.Pointer, n uintptr)
|
||||||
|
|
||||||
func memequal(x, y *any, size uintptr) bool
|
func memequal(x, y *any, size uintptr) bool
|
||||||
|
func memequal0(x, y *any) bool
|
||||||
func memequal8(x, y *any) bool
|
func memequal8(x, y *any) bool
|
||||||
func memequal16(x, y *any) bool
|
func memequal16(x, y *any) bool
|
||||||
func memequal32(x, y *any) bool
|
func memequal32(x, y *any) bool
|
||||||
func memequal64(x, y *any) bool
|
func memequal64(x, y *any) bool
|
||||||
func memequal128(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
|
// only used on 32-bit
|
||||||
func int64div(int64, int64) int64
|
func int64div(int64, int64) int64
|
||||||
|
|
@ -212,7 +235,21 @@ func racewriterange(addr, size uintptr)
|
||||||
func msanread(addr, size uintptr)
|
func msanread(addr, size uintptr)
|
||||||
func msanwrite(addr, size uintptr)
|
func msanwrite(addr, 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
|
// architecture variants
|
||||||
var x86HasPOPCNT bool
|
var x86HasPOPCNT bool
|
||||||
var x86HasSSE41 bool
|
var x86HasSSE41 bool
|
||||||
|
var x86HasFMA bool
|
||||||
|
var armHasVFPv4 bool
|
||||||
var arm64HasATOMICS bool
|
var arm64HasATOMICS bool
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,11 @@ func _() {
|
||||||
_ = x[PPARAM-4]
|
_ = x[PPARAM-4]
|
||||||
_ = x[PPARAMOUT-5]
|
_ = x[PPARAMOUT-5]
|
||||||
_ = x[PFUNC-6]
|
_ = x[PFUNC-6]
|
||||||
_ = x[PDISCARD-7]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const _Class_name = "PxxxPEXTERNPAUTOPAUTOHEAPPPARAMPPARAMOUTPFUNCPDISCARD"
|
const _Class_name = "PxxxPEXTERNPAUTOPAUTOHEAPPPARAMPPARAMOUTPFUNC"
|
||||||
|
|
||||||
var _Class_index = [...]uint8{0, 4, 11, 16, 25, 31, 40, 45, 53}
|
var _Class_index = [...]uint8{0, 4, 11, 16, 25, 31, 40, 45}
|
||||||
|
|
||||||
func (i Class) String() string {
|
func (i Class) String() string {
|
||||||
if i >= Class(len(_Class_index)-1) {
|
if i >= Class(len(_Class_index)-1) {
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,13 @@ func (p *noder) funcLit(expr *syntax.FuncLit) *Node {
|
||||||
|
|
||||||
func typecheckclosure(clo *Node, top int) {
|
func typecheckclosure(clo *Node, top int) {
|
||||||
xfunc := clo.Func.Closure
|
xfunc := clo.Func.Closure
|
||||||
clo.Func.Ntype = typecheck(clo.Func.Ntype, Etype)
|
// 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.Type = clo.Func.Ntype.Type
|
||||||
clo.Func.Top = top
|
clo.Func.Top = top
|
||||||
|
|
||||||
|
|
@ -95,7 +101,7 @@ func typecheckclosure(clo *Node, top int) {
|
||||||
// Ignore assignments to the variable in straightline code
|
// Ignore assignments to the variable in straightline code
|
||||||
// preceding the first capturing by a closure.
|
// preceding the first capturing by a closure.
|
||||||
if n.Name.Decldepth == decldepth {
|
if n.Name.Decldepth == decldepth {
|
||||||
n.SetAssigned(false)
|
n.Name.SetAssigned(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -186,10 +192,10 @@ func capturevars(xfunc *Node) {
|
||||||
outermost := v.Name.Defn
|
outermost := v.Name.Defn
|
||||||
|
|
||||||
// out parameters will be assigned to implicitly upon return.
|
// out parameters will be assigned to implicitly upon return.
|
||||||
if outermost.Class() != PPARAMOUT && !outermost.Addrtaken() && !outermost.Assigned() && v.Type.Width <= 128 {
|
if outermost.Class() != PPARAMOUT && !outermost.Name.Addrtaken() && !outermost.Name.Assigned() && v.Type.Width <= 128 {
|
||||||
v.Name.SetByval(true)
|
v.Name.SetByval(true)
|
||||||
} else {
|
} else {
|
||||||
outermost.SetAddrtaken(true)
|
outermost.Name.SetAddrtaken(true)
|
||||||
outer = nod(OADDR, outer, nil)
|
outer = nod(OADDR, outer, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,7 +208,7 @@ func capturevars(xfunc *Node) {
|
||||||
if v.Name.Byval() {
|
if v.Name.Byval() {
|
||||||
how = "value"
|
how = "value"
|
||||||
}
|
}
|
||||||
Warnl(v.Pos, "%v capturing by %s: %v (addr=%v assign=%v width=%d)", name, how, v.Sym, outermost.Addrtaken(), outermost.Assigned(), int32(v.Type.Width))
|
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)
|
outer = typecheck(outer, ctxExpr)
|
||||||
|
|
@ -339,7 +345,7 @@ func closuredebugruntimecheck(clo *Node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if compiling_runtime && clo.Esc == EscHeap {
|
if compiling_runtime && clo.Esc == EscHeap {
|
||||||
yyerrorl(clo.Pos, "heap-allocated closure, not allowed in runtime.")
|
yyerrorl(clo.Pos, "heap-allocated closure, not allowed in runtime")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -389,18 +395,16 @@ func walkclosure(clo *Node, init *Nodes) *Node {
|
||||||
|
|
||||||
typ := closureType(clo)
|
typ := closureType(clo)
|
||||||
|
|
||||||
clos := nod(OCOMPLIT, nil, nod(ODEREF, typenod(typ), nil))
|
clos := nod(OCOMPLIT, nil, typenod(typ))
|
||||||
clos.Esc = clo.Esc
|
clos.Esc = clo.Esc
|
||||||
clos.Right.SetImplicit(true)
|
|
||||||
clos.List.Set(append([]*Node{nod(OCFUNC, xfunc.Func.Nname, nil)}, clo.Func.Enter.Slice()...))
|
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.
|
// Force type conversion from *struct to the func type.
|
||||||
clos = convnop(clos, clo.Type)
|
clos = convnop(clos, clo.Type)
|
||||||
|
|
||||||
// typecheck will insert a PTRLIT node under CONVNOP,
|
|
||||||
// tag it with escape analysis result.
|
|
||||||
clos.Left.Esc = clo.Esc
|
|
||||||
|
|
||||||
// non-escaping temp to use, if any.
|
// non-escaping temp to use, if any.
|
||||||
if x := prealloc[clo]; x != nil {
|
if x := prealloc[clo]; x != nil {
|
||||||
if !types.Identical(typ, x.Type) {
|
if !types.Identical(typ, x.Type) {
|
||||||
|
|
@ -541,18 +545,16 @@ func walkpartialcall(n *Node, init *Nodes) *Node {
|
||||||
|
|
||||||
typ := partialCallType(n)
|
typ := partialCallType(n)
|
||||||
|
|
||||||
clos := nod(OCOMPLIT, nil, nod(ODEREF, typenod(typ), nil))
|
clos := nod(OCOMPLIT, nil, typenod(typ))
|
||||||
clos.Esc = n.Esc
|
clos.Esc = n.Esc
|
||||||
clos.Right.SetImplicit(true)
|
|
||||||
clos.List.Set2(nod(OCFUNC, n.Func.Nname, nil), n.Left)
|
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.
|
// Force type conversion from *struct to the func type.
|
||||||
clos = convnop(clos, n.Type)
|
clos = convnop(clos, n.Type)
|
||||||
|
|
||||||
// The typecheck inside convnop will insert a PTRLIT node under CONVNOP.
|
|
||||||
// Tag it with escape analysis result.
|
|
||||||
clos.Left.Esc = n.Esc
|
|
||||||
|
|
||||||
// non-escaping temp to use, if any.
|
// non-escaping temp to use, if any.
|
||||||
if x := prealloc[n]; x != nil {
|
if x := prealloc[n]; x != nil {
|
||||||
if !types.Identical(typ, x.Type) {
|
if !types.Identical(typ, x.Type) {
|
||||||
|
|
|
||||||
|
|
@ -204,228 +204,209 @@ func trunccmplxlit(oldv *Mpcplx, t *types.Type) *Mpcplx {
|
||||||
return cv
|
return cv
|
||||||
}
|
}
|
||||||
|
|
||||||
// canReuseNode indicates whether it is known to be safe
|
// TODO(mdempsky): Replace these with better APIs.
|
||||||
// to reuse a Node.
|
func convlit(n *Node, t *types.Type) *Node { return convlit1(n, t, false, nil) }
|
||||||
type canReuseNode bool
|
func defaultlit(n *Node, t *types.Type) *Node { return convlit1(n, t, false, nil) }
|
||||||
|
|
||||||
const (
|
// convlit1 converts an untyped expression n to type t. If n already
|
||||||
noReuse canReuseNode = false // not necessarily safe to reuse
|
// has a type, convlit1 has no effect.
|
||||||
reuseOK canReuseNode = true // safe to reuse
|
//
|
||||||
)
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
// convert n, if literal, to type t.
|
if n == nil || n.Type == nil {
|
||||||
// implicit conversion.
|
// Allow sloppy callers.
|
||||||
// The result of convlit MUST be assigned back to n, e.g.
|
|
||||||
// n.Left = convlit(n.Left, t)
|
|
||||||
func convlit(n *Node, t *types.Type) *Node {
|
|
||||||
return convlit1(n, t, false, noReuse)
|
|
||||||
}
|
|
||||||
|
|
||||||
// convlit1 converts n, if literal, to type t.
|
|
||||||
// It returns a new node if necessary.
|
|
||||||
// The result of convlit1 MUST be assigned back to n, e.g.
|
|
||||||
// n.Left = convlit1(n.Left, t, explicit, reuse)
|
|
||||||
func convlit1(n *Node, t *types.Type, explicit bool, reuse canReuseNode) *Node {
|
|
||||||
if n == nil || t == nil || n.Type == nil || t.IsUntyped() || n.Type == t {
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
if !explicit && !n.Type.IsUntyped() {
|
if !n.Type.IsUntyped() {
|
||||||
|
// Already typed; nothing to do.
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Op == OLITERAL && !reuse {
|
if n.Op == OLITERAL {
|
||||||
// Can't always set n.Type directly on OLITERAL nodes.
|
// Can't always set n.Type directly on OLITERAL nodes.
|
||||||
// See discussion on CL 20813.
|
// See discussion on CL 20813.
|
||||||
n = n.rawcopy()
|
n = n.rawcopy()
|
||||||
reuse = true
|
}
|
||||||
|
|
||||||
|
// 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(idealkind(n))
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
if n.Type == types.Idealbool {
|
Fatalf("unexpected untyped expression: %v", n)
|
||||||
if !t.IsBoolean() {
|
|
||||||
t = types.Types[TBOOL]
|
|
||||||
}
|
|
||||||
switch n.Op {
|
|
||||||
case ONOT:
|
|
||||||
n.Left = convlit(n.Left, t)
|
|
||||||
case OANDAND, OOROR:
|
|
||||||
n.Left = convlit(n.Left, t)
|
|
||||||
n.Right = convlit(n.Right, t)
|
|
||||||
}
|
|
||||||
n.Type = t
|
|
||||||
}
|
|
||||||
|
|
||||||
if n.Type.IsUntyped() {
|
case OLITERAL:
|
||||||
if t.IsInterface() {
|
v := convertVal(n.Val(), t, explicit)
|
||||||
n.Left, n.Right = defaultlit2(n.Left, n.Right, true)
|
if v.U == nil {
|
||||||
n.Type = n.Left.Type // same as n.Right.Type per defaultlit2
|
break
|
||||||
} else {
|
|
||||||
n.Left = convlit(n.Left, t)
|
|
||||||
n.Right = convlit(n.Right, t)
|
|
||||||
n.Type = t
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
n.SetVal(v)
|
||||||
|
n.Type = t
|
||||||
return n
|
return n
|
||||||
|
|
||||||
// target is invalid type for a constant? leave alone.
|
case OPLUS, ONEG, OBITNOT, ONOT, OREAL, OIMAG:
|
||||||
case OLITERAL:
|
ot := operandType(n.Op, t)
|
||||||
if !okforconst[t.Etype] && n.Type.Etype != TNIL {
|
if ot == nil {
|
||||||
return defaultlitreuse(n, nil, reuse)
|
n = defaultlit(n, nil)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
case OLSH, ORSH:
|
n.Left = convlit(n.Left, ot)
|
||||||
n.Left = convlit1(n.Left, t, explicit && n.Left.Type.IsUntyped(), noReuse)
|
if n.Left.Type == nil {
|
||||||
t = n.Left.Type
|
n.Type = nil
|
||||||
if t != nil && t.Etype == TIDEAL && n.Val().Ctype() != CTINT {
|
return n
|
||||||
n.SetVal(toint(n.Val()))
|
|
||||||
}
|
}
|
||||||
if t != nil && !t.IsInteger() {
|
n.Type = t
|
||||||
yyerror("invalid operation: %v (shift of type %v)", n, t)
|
return n
|
||||||
t = nil
|
|
||||||
|
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
|
n.Type = t
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case OCOMPLEX:
|
case OEQ, ONE, OLT, OLE, OGT, OGE:
|
||||||
if n.Type.Etype == TIDEAL {
|
if !t.IsBoolean() {
|
||||||
switch t.Etype {
|
|
||||||
default:
|
|
||||||
// If trying to convert to non-complex type,
|
|
||||||
// leave as complex128 and let typechecker complain.
|
|
||||||
t = types.Types[TCOMPLEX128]
|
|
||||||
fallthrough
|
|
||||||
case types.TCOMPLEX128:
|
|
||||||
n.Type = t
|
|
||||||
n.Left = convlit(n.Left, types.Types[TFLOAT64])
|
|
||||||
n.Right = convlit(n.Right, types.Types[TFLOAT64])
|
|
||||||
|
|
||||||
case TCOMPLEX64:
|
|
||||||
n.Type = t
|
|
||||||
n.Left = convlit(n.Left, types.Types[TFLOAT32])
|
|
||||||
n.Right = convlit(n.Right, types.Types[TFLOAT32])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
// avoid repeated calculations, errors
|
|
||||||
if types.Identical(n.Type, t) {
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
ct := consttype(n)
|
|
||||||
var et types.EType
|
|
||||||
if ct == 0 {
|
|
||||||
goto bad
|
|
||||||
}
|
|
||||||
|
|
||||||
et = t.Etype
|
|
||||||
if et == TINTER {
|
|
||||||
if ct == CTNIL && n.Type == types.Types[TNIL] {
|
|
||||||
n.Type = t
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
return defaultlitreuse(n, nil, reuse)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ct {
|
|
||||||
default:
|
|
||||||
goto bad
|
|
||||||
|
|
||||||
case CTNIL:
|
|
||||||
switch et {
|
|
||||||
default:
|
|
||||||
n.Type = nil
|
|
||||||
goto bad
|
|
||||||
|
|
||||||
// let normal conversion code handle it
|
|
||||||
case TSTRING:
|
|
||||||
return n
|
|
||||||
|
|
||||||
case TARRAY:
|
|
||||||
goto bad
|
|
||||||
|
|
||||||
case TPTR, TUNSAFEPTR:
|
|
||||||
n.SetVal(Val{new(Mpint)})
|
|
||||||
|
|
||||||
case TCHAN, TFUNC, TINTER, TMAP, TSLICE:
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
n.Type = t
|
||||||
|
return n
|
||||||
|
|
||||||
case CTSTR, CTBOOL:
|
case OLSH, ORSH:
|
||||||
if et != n.Type.Etype {
|
n.Left = convlit1(n.Left, t, explicit, nil)
|
||||||
goto bad
|
n.Type = n.Left.Type
|
||||||
}
|
if n.Type != nil && !n.Type.IsInteger() {
|
||||||
|
yyerror("invalid operation: %v (shift of type %v)", n, n.Type)
|
||||||
case CTINT, CTRUNE, CTFLT, CTCPLX:
|
n.Type = nil
|
||||||
if n.Type.Etype == TUNSAFEPTR && t.Etype != TUINTPTR {
|
|
||||||
goto bad
|
|
||||||
}
|
|
||||||
ct := n.Val().Ctype()
|
|
||||||
if isInt[et] {
|
|
||||||
switch ct {
|
|
||||||
default:
|
|
||||||
goto bad
|
|
||||||
|
|
||||||
case CTCPLX, CTFLT, CTRUNE:
|
|
||||||
n.SetVal(toint(n.Val()))
|
|
||||||
fallthrough
|
|
||||||
|
|
||||||
case CTINT:
|
|
||||||
overflow(n.Val(), t)
|
|
||||||
}
|
|
||||||
} else if isFloat[et] {
|
|
||||||
switch ct {
|
|
||||||
default:
|
|
||||||
goto bad
|
|
||||||
|
|
||||||
case CTCPLX, CTINT, CTRUNE:
|
|
||||||
n.SetVal(toflt(n.Val()))
|
|
||||||
fallthrough
|
|
||||||
|
|
||||||
case CTFLT:
|
|
||||||
n.SetVal(Val{truncfltlit(n.Val().U.(*Mpflt), t)})
|
|
||||||
}
|
|
||||||
} else if isComplex[et] {
|
|
||||||
switch ct {
|
|
||||||
default:
|
|
||||||
goto bad
|
|
||||||
|
|
||||||
case CTFLT, CTINT, CTRUNE:
|
|
||||||
n.SetVal(tocplx(n.Val()))
|
|
||||||
fallthrough
|
|
||||||
|
|
||||||
case CTCPLX:
|
|
||||||
n.SetVal(Val{trunccmplxlit(n.Val().U.(*Mpcplx), t)})
|
|
||||||
}
|
|
||||||
} else if et == types.TSTRING && (ct == CTINT || ct == CTRUNE) && explicit {
|
|
||||||
n.SetVal(tostr(n.Val()))
|
|
||||||
} else {
|
|
||||||
goto bad
|
|
||||||
}
|
}
|
||||||
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Type = t
|
|
||||||
return n
|
|
||||||
|
|
||||||
bad:
|
|
||||||
if !n.Diag() {
|
if !n.Diag() {
|
||||||
if !t.Broke() {
|
if !t.Broke() {
|
||||||
yyerror("cannot convert %L to type %v", n, t)
|
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.SetDiag(true)
|
||||||
}
|
}
|
||||||
|
n.Type = nil
|
||||||
if n.Type.IsUntyped() {
|
|
||||||
n = defaultlitreuse(n, nil, reuse)
|
|
||||||
}
|
|
||||||
return n
|
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 {
|
func tocplx(v Val) Val {
|
||||||
switch u := v.U.(type) {
|
switch u := v.U.(type) {
|
||||||
case *Mpint:
|
case *Mpint:
|
||||||
|
|
@ -571,7 +552,7 @@ func tostr(v Val) Val {
|
||||||
|
|
||||||
func consttype(n *Node) Ctype {
|
func consttype(n *Node) Ctype {
|
||||||
if n == nil || n.Op != OLITERAL {
|
if n == nil || n.Op != OLITERAL {
|
||||||
return 0
|
return CTxxx
|
||||||
}
|
}
|
||||||
return n.Val().Ctype()
|
return n.Val().Ctype()
|
||||||
}
|
}
|
||||||
|
|
@ -602,16 +583,7 @@ func evconst(n *Node) {
|
||||||
|
|
||||||
case OEQ, ONE, OLT, OLE, OGT, OGE:
|
case OEQ, ONE, OLT, OLE, OGT, OGE:
|
||||||
if nl.Op == OLITERAL && nr.Op == OLITERAL {
|
if nl.Op == OLITERAL && nr.Op == OLITERAL {
|
||||||
if nl.Type.IsInterface() != nr.Type.IsInterface() {
|
setboolconst(n, compareOp(nl.Val(), op, nr.Val()))
|
||||||
// Mixed interface/non-interface
|
|
||||||
// constant comparison means comparing
|
|
||||||
// nil interface with some typed
|
|
||||||
// constant, which is always unequal.
|
|
||||||
// E.g., interface{}(nil) == (*int)(nil).
|
|
||||||
setboolconst(n, op == ONE)
|
|
||||||
} else {
|
|
||||||
setboolconst(n, compareOp(nl.Val(), op, nr.Val()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case OLSH, ORSH:
|
case OLSH, ORSH:
|
||||||
|
|
@ -619,10 +591,9 @@ func evconst(n *Node) {
|
||||||
setconst(n, shiftOp(nl.Val(), op, nr.Val()))
|
setconst(n, shiftOp(nl.Val(), op, nr.Val()))
|
||||||
}
|
}
|
||||||
|
|
||||||
case OCONV:
|
case OCONV, ORUNESTR:
|
||||||
if okforconst[n.Type.Etype] && nl.Op == OLITERAL {
|
if okforconst[n.Type.Etype] && nl.Op == OLITERAL {
|
||||||
// TODO(mdempsky): There should be a convval function.
|
setconst(n, convertVal(nl.Val(), n.Type, true))
|
||||||
setconst(n, convlit1(nl, n.Type, true, false).Val())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case OCONVNOP:
|
case OCONVNOP:
|
||||||
|
|
@ -641,7 +612,7 @@ func evconst(n *Node) {
|
||||||
var strs []string
|
var strs []string
|
||||||
i2 := i1
|
i2 := i1
|
||||||
for i2 < len(s) && Isconst(s[i2], CTSTR) {
|
for i2 < len(s) && Isconst(s[i2], CTSTR) {
|
||||||
strs = append(strs, s[i2].Val().U.(string))
|
strs = append(strs, strlit(s[i2]))
|
||||||
i2++
|
i2++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -664,7 +635,7 @@ func evconst(n *Node) {
|
||||||
switch nl.Type.Etype {
|
switch nl.Type.Etype {
|
||||||
case TSTRING:
|
case TSTRING:
|
||||||
if Isconst(nl, CTSTR) {
|
if Isconst(nl, CTSTR) {
|
||||||
setintconst(n, int64(len(nl.Val().U.(string))))
|
setintconst(n, int64(len(strlit(nl))))
|
||||||
}
|
}
|
||||||
case TARRAY:
|
case TARRAY:
|
||||||
if !hascallchan(nl) {
|
if !hascallchan(nl) {
|
||||||
|
|
@ -732,15 +703,6 @@ func compareOp(x Val, op Op, y Val) bool {
|
||||||
x, y = match(x, y)
|
x, y = match(x, y)
|
||||||
|
|
||||||
switch x.Ctype() {
|
switch x.Ctype() {
|
||||||
case CTNIL:
|
|
||||||
_, _ = x.U.(*NilVal), y.U.(*NilVal) // assert dynamic types match
|
|
||||||
switch op {
|
|
||||||
case OEQ:
|
|
||||||
return true
|
|
||||||
case ONE:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
case CTBOOL:
|
case CTBOOL:
|
||||||
x, y := x.U.(bool), y.U.(bool)
|
x, y := x.U.(bool), y.U.(bool)
|
||||||
switch op {
|
switch op {
|
||||||
|
|
@ -1036,15 +998,26 @@ func setconst(n *Node, v Val) {
|
||||||
Xoffset: BADWIDTH,
|
Xoffset: BADWIDTH,
|
||||||
}
|
}
|
||||||
n.SetVal(v)
|
n.SetVal(v)
|
||||||
|
if n.Type.IsUntyped() {
|
||||||
|
// TODO(mdempsky): Make typecheck responsible for setting
|
||||||
|
// the correct untyped type.
|
||||||
|
n.Type = idealType(v.Ctype())
|
||||||
|
}
|
||||||
|
|
||||||
// Check range.
|
// Check range.
|
||||||
lno := setlineno(n)
|
lno := setlineno(n)
|
||||||
overflow(v, n.Type)
|
overflow(v, n.Type)
|
||||||
lineno = lno
|
lineno = lno
|
||||||
|
|
||||||
// Truncate precision for non-ideal float.
|
if !n.Type.IsUntyped() {
|
||||||
if v.Ctype() == CTFLT && n.Type.Etype != TIDEAL {
|
switch v.Ctype() {
|
||||||
n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)})
|
// 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)})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1062,26 +1035,31 @@ func setintconst(n *Node, v int64) {
|
||||||
func nodlit(v Val) *Node {
|
func nodlit(v Val) *Node {
|
||||||
n := nod(OLITERAL, nil, nil)
|
n := nod(OLITERAL, nil, nil)
|
||||||
n.SetVal(v)
|
n.SetVal(v)
|
||||||
switch v.Ctype() {
|
n.Type = idealType(v.Ctype())
|
||||||
default:
|
|
||||||
Fatalf("nodlit ctype %d", v.Ctype())
|
|
||||||
|
|
||||||
case CTSTR:
|
|
||||||
n.Type = types.Idealstring
|
|
||||||
|
|
||||||
case CTBOOL:
|
|
||||||
n.Type = types.Idealbool
|
|
||||||
|
|
||||||
case CTINT, CTRUNE, CTFLT, CTCPLX:
|
|
||||||
n.Type = types.Types[TIDEAL]
|
|
||||||
|
|
||||||
case CTNIL:
|
|
||||||
n.Type = types.Types[TNIL]
|
|
||||||
}
|
|
||||||
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func idealType(ct Ctype) *types.Type {
|
||||||
|
switch ct {
|
||||||
|
case CTSTR:
|
||||||
|
return types.Idealstring
|
||||||
|
case CTBOOL:
|
||||||
|
return types.Idealbool
|
||||||
|
case CTINT:
|
||||||
|
return types.Idealint
|
||||||
|
case CTRUNE:
|
||||||
|
return types.Idealrune
|
||||||
|
case CTFLT:
|
||||||
|
return types.Idealfloat
|
||||||
|
case CTCPLX:
|
||||||
|
return types.Idealcomplex
|
||||||
|
case CTNIL:
|
||||||
|
return types.Types[TNIL]
|
||||||
|
}
|
||||||
|
Fatalf("unexpected Ctype: %v", ct)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// idealkind returns a constant kind like consttype
|
// idealkind returns a constant kind like consttype
|
||||||
// but for an arbitrary "ideal" (untyped constant) expression.
|
// but for an arbitrary "ideal" (untyped constant) expression.
|
||||||
func idealkind(n *Node) Ctype {
|
func idealkind(n *Node) Ctype {
|
||||||
|
|
@ -1143,100 +1121,6 @@ func idealkind(n *Node) Ctype {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The result of defaultlit MUST be assigned back to n, e.g.
|
|
||||||
// n.Left = defaultlit(n.Left, t)
|
|
||||||
func defaultlit(n *Node, t *types.Type) *Node {
|
|
||||||
return defaultlitreuse(n, t, noReuse)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The result of defaultlitreuse MUST be assigned back to n, e.g.
|
|
||||||
// n.Left = defaultlitreuse(n.Left, t, reuse)
|
|
||||||
func defaultlitreuse(n *Node, t *types.Type, reuse canReuseNode) *Node {
|
|
||||||
if n == nil || !n.Type.IsUntyped() {
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
if n.Op == OLITERAL && !reuse {
|
|
||||||
n = n.rawcopy()
|
|
||||||
reuse = true
|
|
||||||
}
|
|
||||||
|
|
||||||
lno := setlineno(n)
|
|
||||||
ctype := idealkind(n)
|
|
||||||
var t1 *types.Type
|
|
||||||
switch ctype {
|
|
||||||
default:
|
|
||||||
if t != nil {
|
|
||||||
return convlit(n, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch n.Val().Ctype() {
|
|
||||||
case CTNIL:
|
|
||||||
lineno = lno
|
|
||||||
if !n.Diag() {
|
|
||||||
yyerror("use of untyped nil")
|
|
||||||
n.SetDiag(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
n.Type = nil
|
|
||||||
case CTSTR:
|
|
||||||
t1 := types.Types[TSTRING]
|
|
||||||
n = convlit1(n, t1, false, reuse)
|
|
||||||
default:
|
|
||||||
yyerror("defaultlit: unknown literal: %v", n)
|
|
||||||
}
|
|
||||||
lineno = lno
|
|
||||||
return n
|
|
||||||
|
|
||||||
case CTxxx:
|
|
||||||
Fatalf("defaultlit: idealkind is CTxxx: %+v", n)
|
|
||||||
|
|
||||||
case CTBOOL:
|
|
||||||
t1 := types.Types[TBOOL]
|
|
||||||
if t != nil && t.IsBoolean() {
|
|
||||||
t1 = t
|
|
||||||
}
|
|
||||||
n = convlit1(n, t1, false, reuse)
|
|
||||||
lineno = lno
|
|
||||||
return n
|
|
||||||
|
|
||||||
case CTINT:
|
|
||||||
t1 = types.Types[TINT]
|
|
||||||
case CTRUNE:
|
|
||||||
t1 = types.Runetype
|
|
||||||
case CTFLT:
|
|
||||||
t1 = types.Types[TFLOAT64]
|
|
||||||
case CTCPLX:
|
|
||||||
t1 = types.Types[TCOMPLEX128]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: n.Val().Ctype() can be CTxxx (not a constant) here
|
|
||||||
// in the case of an untyped non-constant value, like 1<<i.
|
|
||||||
v1 := n.Val()
|
|
||||||
if t != nil {
|
|
||||||
if t.IsInteger() {
|
|
||||||
t1 = t
|
|
||||||
v1 = toint(n.Val())
|
|
||||||
} else if t.IsFloat() {
|
|
||||||
t1 = t
|
|
||||||
v1 = toflt(n.Val())
|
|
||||||
} else if t.IsComplex() {
|
|
||||||
t1 = t
|
|
||||||
v1 = tocplx(n.Val())
|
|
||||||
}
|
|
||||||
if n.Val().Ctype() != CTxxx {
|
|
||||||
n.SetVal(v1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if n.Val().Ctype() != CTxxx {
|
|
||||||
overflow(n.Val(), t1)
|
|
||||||
}
|
|
||||||
n = convlit1(n, t1, false, reuse)
|
|
||||||
lineno = lno
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
// defaultlit on both nodes simultaneously;
|
// defaultlit on both nodes simultaneously;
|
||||||
// if they're both ideal going in they better
|
// if they're both ideal going in they better
|
||||||
// get the same type going out.
|
// get the same type going out.
|
||||||
|
|
@ -1261,37 +1145,46 @@ func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) {
|
||||||
return l, r
|
return l, r
|
||||||
}
|
}
|
||||||
|
|
||||||
if l.Type.IsBoolean() {
|
// Can't mix bool with non-bool, string with non-string, or nil with anything (untyped).
|
||||||
l = convlit(l, types.Types[TBOOL])
|
if l.Type.IsBoolean() != r.Type.IsBoolean() {
|
||||||
r = convlit(r, types.Types[TBOOL])
|
return l, r
|
||||||
}
|
}
|
||||||
|
if l.Type.IsString() != r.Type.IsString() {
|
||||||
lkind := idealkind(l)
|
return l, r
|
||||||
rkind := idealkind(r)
|
}
|
||||||
if lkind == CTCPLX || rkind == CTCPLX {
|
if l.isNil() || r.isNil() {
|
||||||
l = convlit(l, types.Types[TCOMPLEX128])
|
|
||||||
r = convlit(r, types.Types[TCOMPLEX128])
|
|
||||||
return l, r
|
return l, r
|
||||||
}
|
}
|
||||||
|
|
||||||
if lkind == CTFLT || rkind == CTFLT {
|
k := idealkind(l)
|
||||||
l = convlit(l, types.Types[TFLOAT64])
|
if rk := idealkind(r); rk > k {
|
||||||
r = convlit(r, types.Types[TFLOAT64])
|
k = rk
|
||||||
return l, r
|
|
||||||
}
|
}
|
||||||
|
t := defaultType(k)
|
||||||
if lkind == CTRUNE || rkind == CTRUNE {
|
l = convlit(l, t)
|
||||||
l = convlit(l, types.Runetype)
|
r = convlit(r, t)
|
||||||
r = convlit(r, types.Runetype)
|
|
||||||
return l, r
|
|
||||||
}
|
|
||||||
|
|
||||||
l = convlit(l, types.Types[TINT])
|
|
||||||
r = convlit(r, types.Types[TINT])
|
|
||||||
|
|
||||||
return l, r
|
return l, r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func defaultType(k Ctype) *types.Type {
|
||||||
|
switch k {
|
||||||
|
case CTBOOL:
|
||||||
|
return types.Types[TBOOL]
|
||||||
|
case CTSTR:
|
||||||
|
return types.Types[TSTRING]
|
||||||
|
case CTINT:
|
||||||
|
return types.Types[TINT]
|
||||||
|
case CTRUNE:
|
||||||
|
return types.Runetype
|
||||||
|
case CTFLT:
|
||||||
|
return types.Types[TFLOAT64]
|
||||||
|
case CTCPLX:
|
||||||
|
return types.Types[TCOMPLEX128]
|
||||||
|
}
|
||||||
|
Fatalf("bad idealkind: %v", k)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// strlit returns the value of a literal string Node as a string.
|
// strlit returns the value of a literal string Node as a string.
|
||||||
func strlit(n *Node) string {
|
func strlit(n *Node) string {
|
||||||
return n.Val().U.(string)
|
return n.Val().U.(string)
|
||||||
|
|
@ -1411,7 +1304,7 @@ type constSetKey struct {
|
||||||
// equal value and identical type has already been added, then add
|
// equal value and identical type has already been added, then add
|
||||||
// reports an error about the duplicate value.
|
// reports an error about the duplicate value.
|
||||||
//
|
//
|
||||||
// pos provides position information for where expression n occured
|
// pos provides position information for where expression n occurred
|
||||||
// (in case n does not have its own position information). what and
|
// (in case n does not have its own position information). what and
|
||||||
// where are used in the error message.
|
// where are used in the error message.
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -60,10 +60,6 @@ var declare_typegen int
|
||||||
// declare records that Node n declares symbol n.Sym in the specified
|
// declare records that Node n declares symbol n.Sym in the specified
|
||||||
// declaration context.
|
// declaration context.
|
||||||
func declare(n *Node, ctxt Class) {
|
func declare(n *Node, ctxt Class) {
|
||||||
if ctxt == PDISCARD {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if n.isBlank() {
|
if n.isBlank() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -207,7 +203,6 @@ func newnoname(s *types.Sym) *Node {
|
||||||
}
|
}
|
||||||
n := nod(ONONAME, nil, nil)
|
n := nod(ONONAME, nil, nil)
|
||||||
n.Sym = s
|
n.Sym = s
|
||||||
n.SetAddable(true)
|
|
||||||
n.Xoffset = 0
|
n.Xoffset = 0
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -283,10 +278,9 @@ func oldname(s *types.Sym) *Node {
|
||||||
// Do not have a closure var for the active closure yet; make one.
|
// Do not have a closure var for the active closure yet; make one.
|
||||||
c = newname(s)
|
c = newname(s)
|
||||||
c.SetClass(PAUTOHEAP)
|
c.SetClass(PAUTOHEAP)
|
||||||
c.SetIsClosureVar(true)
|
c.Name.SetIsClosureVar(true)
|
||||||
c.SetIsDDD(n.IsDDD())
|
c.SetIsDDD(n.IsDDD())
|
||||||
c.Name.Defn = n
|
c.Name.Defn = n
|
||||||
c.SetAddable(false)
|
|
||||||
|
|
||||||
// Link into list of active closure variables.
|
// Link into list of active closure variables.
|
||||||
// Popped from list in func closurebody.
|
// Popped from list in func closurebody.
|
||||||
|
|
@ -544,7 +538,7 @@ func structfield(n *Node) *types.Field {
|
||||||
f.Sym = n.Sym
|
f.Sym = n.Sym
|
||||||
|
|
||||||
if n.Left != nil {
|
if n.Left != nil {
|
||||||
n.Left = typecheck(n.Left, Etype)
|
n.Left = typecheck(n.Left, ctxType)
|
||||||
n.Type = n.Left.Type
|
n.Type = n.Left.Type
|
||||||
n.Left = nil
|
n.Left = nil
|
||||||
}
|
}
|
||||||
|
|
@ -668,7 +662,7 @@ func interfacefield(n *Node) *types.Field {
|
||||||
// Otherwise, Left is InterfaceTypeName.
|
// Otherwise, Left is InterfaceTypeName.
|
||||||
|
|
||||||
if n.Left != nil {
|
if n.Left != nil {
|
||||||
n.Left = typecheck(n.Left, Etype)
|
n.Left = typecheck(n.Left, ctxType)
|
||||||
n.Type = n.Left.Type
|
n.Type = n.Left.Type
|
||||||
n.Left = nil
|
n.Left = nil
|
||||||
}
|
}
|
||||||
|
|
@ -1020,7 +1014,7 @@ func dclfunc(sym *types.Sym, tfn *Node) *Node {
|
||||||
fn.Func.Nname.Name.Param.Ntype = tfn
|
fn.Func.Nname.Name.Param.Ntype = tfn
|
||||||
declare(fn.Func.Nname, PFUNC)
|
declare(fn.Func.Nname, PFUNC)
|
||||||
funchdr(fn)
|
funchdr(fn)
|
||||||
fn.Func.Nname.Name.Param.Ntype = typecheck(fn.Func.Nname.Name.Param.Ntype, Etype)
|
fn.Func.Nname.Name.Param.Ntype = typecheck(fn.Func.Nname.Name.Param.Ntype, ctxType)
|
||||||
return fn
|
return fn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue