mirror of
https://github.com/golang/go.git
synced 2026-01-30 23:52:05 +03:00
Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
883bc6ed0e | ||
|
|
5e9b6cac52 | ||
|
|
e4acac3dfb | ||
|
|
3e5977f99d | ||
|
|
02cf0526bf | ||
|
|
3124622303 | ||
|
|
a255645770 | ||
|
|
2b7d0b4c0d | ||
|
|
5caa9d15f2 | ||
|
|
b64f8f8764 | ||
|
|
15ce943f15 | ||
|
|
886b02d705 | ||
|
|
590548d7bd | ||
|
|
00d88f68bb | ||
|
|
cece1bd03f | ||
|
|
ac15ad8a38 | ||
|
|
7df87f5066 | ||
|
|
97b84fc4c8 | ||
|
|
add1ee0ed5 | ||
|
|
d9e0ca4055 | ||
|
|
ff2ab29914 | ||
|
|
6609baf2f7 | ||
|
|
957ed90d0e | ||
|
|
cc7bbb0ae9 | ||
|
|
4482c7b1a1 | ||
|
|
7cb53b8ca2 | ||
|
|
c303df658d | ||
|
|
75b53641f2 | ||
|
|
7412503a43 | ||
|
|
aec78b7a61 | ||
|
|
031850b689 | ||
|
|
f9ae81edca | ||
|
|
9820fbcf7b | ||
|
|
d88fe6146d | ||
|
|
c089afbbd7 | ||
|
|
05560adf62 | ||
|
|
c139772a39 | ||
|
|
c009bcdd8b | ||
|
|
75c8a78e61 | ||
|
|
f42f5263ad | ||
|
|
59730b3343 | ||
|
|
7aead4c6fd | ||
|
|
19bbff8a32 | ||
|
|
c29baa647e | ||
|
|
4d1f720b70 | ||
|
|
79a3df47aa | ||
|
|
3d34461177 | ||
|
|
28208eb8e3 | ||
|
|
95e92ac420 | ||
|
|
783ad67982 | ||
|
|
d3ae115c41 | ||
|
|
738ccf32d9 | ||
|
|
f6818121ed | ||
|
|
791fec05e4 | ||
|
|
a791780bfd | ||
|
|
427ee80413 | ||
|
|
b4df0154c2 | ||
|
|
c9e183e781 | ||
|
|
30ef146819 | ||
|
|
daf5d41471 | ||
|
|
c1fc059b08 | ||
|
|
335ad3db99 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -26,14 +26,15 @@ misc/cgo/life/run.out
|
||||
misc/cgo/stdio/run.out
|
||||
misc/cgo/testso/main
|
||||
misc/dashboard/builder/builder
|
||||
src/cmd/?a/y.output
|
||||
src/liblink/anames?.c
|
||||
src/cmd/*/y.output
|
||||
src/cmd/cc/y.output
|
||||
src/cmd/cgo/zdefaultcc.go
|
||||
src/cmd/dist/dist.dSYM
|
||||
src/cmd/gc/mkbuiltin1
|
||||
src/cmd/gc/opnames.h
|
||||
src/cmd/gc/y.output
|
||||
src/cmd/go/zdefaultcc.go
|
||||
src/cmd/internal/obj/zbootstrap.go
|
||||
src/go/doc/headscan
|
||||
src/runtime/mkversion
|
||||
src/runtime/zaexperiment.h
|
||||
|
||||
58
.hgignore
Normal file
58
.hgignore
Normal file
@@ -0,0 +1,58 @@
|
||||
syntax:glob
|
||||
.DS_Store
|
||||
.git
|
||||
.gitignore
|
||||
*.[568ao]
|
||||
*.a[568o]
|
||||
*.so
|
||||
*.pyc
|
||||
._*
|
||||
.nfs.*
|
||||
[568a].out
|
||||
*~
|
||||
*.orig
|
||||
*.rej
|
||||
*.exe
|
||||
.*.swp
|
||||
core
|
||||
*.cgo*.go
|
||||
*.cgo*.c
|
||||
_cgo_*
|
||||
_obj
|
||||
_test
|
||||
_testmain.go
|
||||
build.out
|
||||
test.out
|
||||
doc/articles/wiki/*.bin
|
||||
include/plan9/libc_plan9.h
|
||||
misc/cgo/life/run.out
|
||||
misc/cgo/stdio/run.out
|
||||
misc/cgo/testso/main
|
||||
misc/dashboard/builder/builder
|
||||
src/cmd/?a/y.output
|
||||
src/liblink/anames?.c
|
||||
src/cmd/cc/y.output
|
||||
src/cmd/cgo/zdefaultcc.go
|
||||
src/cmd/dist/dist.dSYM
|
||||
src/cmd/gc/mkbuiltin1
|
||||
src/cmd/gc/opnames.h
|
||||
src/cmd/gc/y.output
|
||||
src/cmd/go/zdefaultcc.go
|
||||
src/go/doc/headscan
|
||||
src/runtime/mkversion
|
||||
src/runtime/z*
|
||||
src/unicode/maketables
|
||||
src/*.*/
|
||||
test/pass.out
|
||||
test/run.out
|
||||
test/times.out
|
||||
test/garbage/*.out
|
||||
goinstall.log
|
||||
last-change
|
||||
VERSION.cache
|
||||
|
||||
syntax:regexp
|
||||
^bin/
|
||||
^pkg/
|
||||
^src/cmd/(.*)/6?\1$
|
||||
^.*/core.[0-9]*$
|
||||
138
.hgtags
Normal file
138
.hgtags
Normal file
@@ -0,0 +1,138 @@
|
||||
1f0a01c93d305f1ab636c68b67346659c5b957f7 weekly.2009-11-06
|
||||
64e703cb307da550861fe740ff70a482a2c14819 weekly.2009-11-10
|
||||
b51fd2d6c16034480f26c96ba32a11c598e4638e weekly.2009-11-10.1
|
||||
cb140bac9ab0fd9f734ee443cea9ebadc9c99737 weekly.2009-11-12
|
||||
d1b75410b793309532352a6fb6b44453f052f3f4 weekly.2009-11-17
|
||||
e205103b02e7393d4719df5faac2dac808234d3f weekly.2009-12-07
|
||||
3a47d2e3882bb12129de05382a2c131bb0c00964 weekly.2009-12-09
|
||||
a6fcf4303b0a92cce4011556b1c96044252d93af weekly.2009-12-22
|
||||
3887d4d81bca78b63d620985d93f1cc06c063871 weekly.2010-01-05
|
||||
40dd722155f6d0c83fa572c1a5abf7c6ff35049f weekly.2010-01-13
|
||||
0a2770db06efe92b08b5c6f30e14b7e8db012538 weekly.2010-01-27
|
||||
db4262ce882d8445764312d41547ee8f11a7f7a9 weekly.2010-02-04
|
||||
53fec18b83e2b93baafba4733b59bb86b8c1988e weekly.2010-02-17
|
||||
4a0661b86e50eae734dbe43ed1312c4a0304676b weekly.2010-02-23
|
||||
a215d03e7ee1013b2abe3f1e2c84457ec51c68e4 weekly.2010-03-04
|
||||
194d473264c1a015803d07bed200e0c312aca43e weekly.2010-03-15
|
||||
9482fde11a02ffd57ba0561dc8a4ac338061a3ae weekly.2010-03-22
|
||||
57380d620ee6b65eb88da1c52784b62c94d7e72e weekly.2010-03-30
|
||||
f98f784927abc56a61501eba0cf225966f2b0142 weekly.2010-04-13
|
||||
6cc6c0d85fc3234fc0a5ec0a8777aa9d59d05ae8 weekly.2010-04-27
|
||||
17ded5ad443b41ac05924864798f1bd8750da344 weekly.2010-05-04
|
||||
a85ad0a640154b5d33626ad8ea15ed17e3828178 weekly.2010-05-27
|
||||
f776656df34c009f2aad142bf7b34a778404acd1 weekly.2010-06-09
|
||||
113ec27f29f18825444f6f8a3cdc156c1df28e87 weekly.2010-06-21
|
||||
b761e0299e9bf66298778cf170b0f64216e3cf7d weekly.2010-07-01
|
||||
5992bf56aa72efcea87d8dff14985fc8fcc68575 weekly.2010-07-14
|
||||
db904d88dc0ebf6ee5b55e44088915695c1223ee weekly.2010-07-29
|
||||
8884f7b4c7750481ed246c249db47b61fe752c56 weekly.2010-08-04
|
||||
07d3a97302be88af68acff34c8a089589da21d18 weekly.2010-08-11
|
||||
18926649cda7498b8aa539b3a611abcff548f09f weekly.2010-08-25
|
||||
92fcf05736e8565a485adc52da1894270e06ed09 weekly.2010-09-06
|
||||
9329773e204fed50ec686ee78cc715b624bf1b1d weekly.2010-09-15
|
||||
1eec33c03bceef5d7607ea4636185f7bf773e0e4 weekly.2010-09-22
|
||||
c2b8c9f13fb8ad2b56920d9da2928c5314ebf725 weekly.2010-09-29
|
||||
7c2e97710bf49cdbe388260958a6674afefb6c0f weekly.2010-10-13
|
||||
ca4f9687cec0b9c4732afd57b8c2786c7fe242de weekly.2010-10-13.1
|
||||
79997f0e5823ee9d13a34ca9971a9d8811df1c4a weekly.2010-10-20
|
||||
4d5b0816392116d3a3452bb275b6dab6c6456278 weekly.2010-10-27
|
||||
c627e23260c7ddf4a1fcda6ef3197c98fa22551d weekly.2010-11-02
|
||||
a7800e20064a39585aa3ee339c2b7454ae1ce6d5 weekly.2010-11-10
|
||||
c5287468fcff0f8a7bb9ffaece2a4863e7e5d83e weekly.2010-11-23
|
||||
f7e692dc29b02fba8e5d59b967880a347b53607c weekly.2010-12-02
|
||||
56e39c466cc1c49b587eb56dc2166d61151637df weekly.2010-12-08
|
||||
26f4898dc1ca18bb77f9968aca23773637e34f0d weekly.2010-12-15
|
||||
61b2c52b0d2246430395f2869d7b34e565333cf5 weekly.2010-12-15.1
|
||||
51c777dbccb9f537ebffb99244f521c05bf65df6 weekly.2010-12-22
|
||||
8eeee945e358f19405e81792db0e16a1cad14bc0 weekly.2011-01-06
|
||||
514c7ba501a1dd74d69ea2d0a2b4116802ada2b5 weekly.2011-01-12
|
||||
72f9cb714f08b98c6a65ab2f2256fad6bb16967a weekly.2011-01-19
|
||||
d8ba80011a986470a54e5262ec125105aa4adc34 weekly.2011-01-20
|
||||
5b98b59dd37292e36afb24babb2d22758928e13d weekly.2011-02-01
|
||||
867d37fb41a4d96ab7a6202fd6ad54c345494051 weekly.2011-02-01.1
|
||||
b2be017f91348d5f8cbaf42f77a99fc905044b59 weekly.2011-02-15
|
||||
322350d6fdbf11d9c404d6fc766349d824031339 weekly.2011-02-24
|
||||
21848430d60167817ca965c813a2118068ca660f weekly.2011-03-07
|
||||
c5c62aeb6267e124cf05f9622e28dbd0dc6b971d weekly.2011-03-07.1
|
||||
c5c62aeb6267e124cf05f9622e28dbd0dc6b971d release.r56
|
||||
3b4e9c85b643a35860805718323b05186dd7f235 weekly.2011-03-15
|
||||
b84e614e25161f626a6102813c41a80a15e3a625 weekly.2011-03-28
|
||||
cd89452cfea3d125aaf75a1ec8004e2f6a868d38 weekly.2011-04-04
|
||||
d6903b7fbff40c13ee7ea3177c0ae54c7f89d2e6 weekly.2011-04-13
|
||||
2f0fa51fa2da6ab50fcebba526326153da8ed999 weekly.2011-04-27
|
||||
8493bb64e5592bd20c0e60e78e7f8052c1276fcf release.r57
|
||||
95d2ce135523c96c4cea049af94ce76dd8c7d981 release.r57.1
|
||||
c98449d685d2b6aa1df9bfd2e1cce9307efb6e00 weekly.2011-05-22
|
||||
3418f22c39eb8299053ae681199ee90f8cd29c6d weekly.2011-06-02
|
||||
c81944152e973a917797679055b8fcdc70fbc802 weekly.2011-06-09
|
||||
9d7967223815ef6415ff01aa0fe6ad38cdbc7810 release.r57.2
|
||||
dac76f0b1a18a5de5b54a1dc0b231aceaf1c8583 weekly.2011-06-16
|
||||
541c445d6c1353fbfa39df7dc4b0eb27558d1fc1 weekly.2011-06-23
|
||||
1b38d90eebcddefabb3901c5bb63c7e2b04a6ec5 release.r58
|
||||
16bfa562ba767aefd82e598da8b15ee4729e23b0 weekly.2011-07-07
|
||||
d292bc7886682d35bb391bf572be28656baee12d release.r58.1
|
||||
3c21f37b25a3f7a1726265c5339c8a7b0b329336 weekly.2011-07-19
|
||||
bb28251f6da4aca85658582c370c7df89d34efd4 weekly.2011-07-29
|
||||
d5785050f61d973fc36775f7bd2e26689529cb3e release.r59
|
||||
c17ce5ec06b4bd5cf6e7ff2ceb0a60c2e40e0b17 weekly.2011-08-10
|
||||
6eb2b9dbe489acb57a2bfc1de31ec2239ed94326 weekly.2011-08-17
|
||||
c934f6f5fe8b30b4b3210ee3f13669e6e4670c32 weekly.2011-09-01
|
||||
c77997547d546c36c7b969586a36de7ceda74e33 weekly.2011-09-07
|
||||
b0819469a6df6029a27192fe7b19a73d97404c63 release.r60
|
||||
8a09ce0cefc64deab4e6d1ed59a08a53e879bbee weekly.2011-09-16
|
||||
fd30c132d1bdeb79f8f111cb721fb1c78b767b27 release.r60.1
|
||||
d7322ae4d055a4cf3efaf842d0717a41acd85bac weekly.2011-09-21
|
||||
32a5db19629897641b2d488de4d1b998942ef80e release.r60.2
|
||||
3bdabf483805fbf0c7ef013fd09bfd6062b9d3f2 weekly.2011-10-06
|
||||
c1702f36df0397c19fc333571a771666029aa37e release.r60.3
|
||||
acaddf1cea75c059d19b20dbef35b20fb3f38954 release.r58.2
|
||||
6d7136d74b656ba6e1194853a9486375005227ef weekly.2011-10-18
|
||||
941b8015061a0f6480954821dd589c60dfe35ed1 weekly.2011-10-25
|
||||
7c1f789e6efd153951e85e3f28722fc69efc2af2 weekly.2011-10-26
|
||||
e69e528f2afc25a8334cfb9359fa4fcdf2a934b6 weekly.2011-11-01
|
||||
780c85032b174c9d4b42adf75d82bc85af7d78d1 weekly.2011-11-02
|
||||
f4397ad6e87c7ce5feac9b01686f1ebd6cbaac4e weekly.2011-11-08
|
||||
2f4482b89a6b5956828872137b6b96636cd904d3 weekly.2011-11-09
|
||||
b4a91b6933748db1a7150c06a1b55ad506e52906 weekly.2011-11-18
|
||||
80db2da6495a20ddff8305c236825811db8c8665 weekly.2011-12-01
|
||||
0beb796b4ef8747af601ed5ea6766d5b1340086b weekly.2011-12-02
|
||||
0c39eee85b0d1606b79c8ebcdeb3b67ed5849e39 weekly.2011-12-06
|
||||
82fdc445f2ff2c85043446eb84a19cc999dfcb95 weekly.2011-12-14
|
||||
4a82689277582a2a60f006e3f158985f2f8d1da3 weekly.2011-12-22
|
||||
354b17404643c0f1a710bdc48927dff02f203ae3 weekly.2012-01-15
|
||||
9f2be4fbbf690b9562c6e98b91daa0003f0913c7 weekly.2012-01-20
|
||||
1107a7d3cb075836387adfab5ce56d1b3e56637d weekly.2012-01-27
|
||||
52ba9506bd993663a0a033c2bd68699e25d061ab weekly.2012-02-07
|
||||
43cf9b39b6477d3144b0353ee91096e55db6107f weekly.2012-02-14
|
||||
96bd78e7d35e892113bdfa1bdc392d3a5f2e644b weekly.2012-02-22
|
||||
f4470a54e6dbcdd52d8d404e12e4754adcd2c948 weekly.2012-03-04
|
||||
3cdba7b0650c6c906ef3e782654f61701abd7dd2 weekly.2012-03-13
|
||||
bce220d0377405146527ab9478867cbc572a6886 weekly.2012-03-22
|
||||
dc5e410f0b4c32ab11dc992593a2bcf5f607381b weekly.2012-03-27
|
||||
dc5e410f0b4c32ab11dc992593a2bcf5f607381b weekly
|
||||
920e9d1ffd1f46665dd152aa9cf3c0f17d68dd88 go1
|
||||
2ccfd4b451d319941bfe3e08037e1462d3c15093 go1.0.1
|
||||
5e806355a9e1491aaab53d3612fed4c550b130c0 go1.0.2
|
||||
2d8bc3c94ecb3ec8f70556d5fd237788903c7281 go1.0.3
|
||||
35da6063e57f8cefc82ba1ea542c4d9393ea9dfd go1.1rc2
|
||||
5a15f0dae37931da46f0356cf4cffe775a061c12 go1.1rc3
|
||||
e570c2daeaca10663d36d6dee7f8d1d76e8f7b92 go1.1
|
||||
a7bd9a33067b3537351276e0178a045748ad046a go1.1.1
|
||||
414057ac1f1fc850957088e4c5e95cdbccd2d594 go1.1.2
|
||||
45475ec7eab1c588fc4210b34d5901b15ca1e479 go1.2rc2
|
||||
7422495a6bf9d5e84828ee466406293be84f565a go1.2rc3
|
||||
94af58f9fd71feda5c316d791ed11aaf015f9e82 go1.2rc4
|
||||
b3d5a20b070a92da2458c5788694d1359b353f4a go1.2rc5
|
||||
87dea3f5ebe7510998c84dbeeec89382b7d42f9c go1.2
|
||||
0ddbdc3c7ce27e66508fe58ab81ff29324786026 go1.2.1
|
||||
9c4fdd8369ca4483fbed1cb8e67f02643ca10f79 go1.2.2
|
||||
f8b50ad4cac4d4c4ecf48324b4f512f65e82cc1c go1.3beta1
|
||||
9e1652c32289c164126b6171f024afad5665fc9e go1.3beta2
|
||||
9d5451df4e53acc58a848005b7ec3a24c4b6050c go1.3rc1
|
||||
3f66a43d5180052e2e1e38d979d1aa5ad05b21f9 go1.3rc2
|
||||
9895f9e36435468d503eaa74ee217f28d5e28dd4 go1.3
|
||||
073fc578434bf3e1e22749b559d273c8da728ebb go1.3.1
|
||||
85518b1d6f8d6e16133b9ed2c9db6807522d37de go1.3.2
|
||||
f44017549ff9c3cc5eef74ebe7276cd0dfc066b6 go1.3.3
|
||||
f44017549ff9c3cc5eef74ebe7276cd0dfc066b6 release
|
||||
1fdfd7dfaedb1b7702141617e621ab7328a236a1 go1.4beta1
|
||||
@@ -1,31 +0,0 @@
|
||||
# Contributing to Go
|
||||
|
||||
Go is an open source project.
|
||||
|
||||
It is the work of hundreds of contributors. We appreciate your help!
|
||||
|
||||
|
||||
## Filing issues
|
||||
|
||||
When filing an issue, make sure to answer these five questions:
|
||||
|
||||
1. What version of Go are you using (`go version`)?
|
||||
2. What operating system and processor architecture are you using?
|
||||
3. What did you do?
|
||||
4. What did you expect to see?
|
||||
5. What did you see instead?
|
||||
|
||||
General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
|
||||
The gophers there will answer or ask you to file an issue if you've tripped over a bug.
|
||||
|
||||
## Contributing code
|
||||
|
||||
Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
|
||||
before sending patches.
|
||||
|
||||
**We do not accept GitHub pull requests**
|
||||
(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review).
|
||||
|
||||
Unless otherwise noted, the Go source files are distributed under
|
||||
the BSD-style license found in the LICENSE file.
|
||||
|
||||
32
README
Normal file
32
README
Normal file
@@ -0,0 +1,32 @@
|
||||
This is the source code repository for the Go programming language.
|
||||
|
||||
For documentation about how to install and use Go,
|
||||
visit http://golang.org/ or load doc/install-source.html
|
||||
in your web browser.
|
||||
|
||||
After installing Go, you can view a nicely formatted
|
||||
doc/install-source.html by running godoc --http=:6060
|
||||
and then visiting http://localhost:6060/doc/install/source.
|
||||
|
||||
Unless otherwise noted, the Go source files are distributed
|
||||
under the BSD-style license found in the LICENSE file.
|
||||
|
||||
--
|
||||
|
||||
Binary Distribution Notes
|
||||
|
||||
If you have just untarred a binary Go distribution, you need to set
|
||||
the environment variable $GOROOT to the full path of the go
|
||||
directory (the one containing this README). You can omit the
|
||||
variable if you unpack it into /usr/local/go, or if you rebuild
|
||||
from sources by running all.bash (see doc/install.html).
|
||||
You should also add the Go binary directory $GOROOT/bin
|
||||
to your shell's path.
|
||||
|
||||
For example, if you extracted the tar file into $HOME/go, you might
|
||||
put the following in your .profile:
|
||||
|
||||
export GOROOT=$HOME/go
|
||||
export PATH=$PATH:$GOROOT/bin
|
||||
|
||||
See doc/install.html for more details.
|
||||
45
README.md
45
README.md
@@ -1,45 +0,0 @@
|
||||
# The Go Programming Language
|
||||
|
||||
Go is an open source programming language that makes it easy to build simple,
|
||||
reliable, and efficient software.
|
||||
|
||||

|
||||
|
||||
For documentation about how to install and use Go,
|
||||
visit https://golang.org/ or load doc/install-source.html
|
||||
in your web browser.
|
||||
|
||||
Our canonical Git repository is located at https://go.googlesource.com/go.
|
||||
There is a mirror of the repository at https://github.com/golang/go.
|
||||
|
||||
Please report issues here: https://golang.org/issue/new
|
||||
|
||||
Go is the work of hundreds of contributors. We appreciate your help!
|
||||
|
||||
To contribute, please read the contribution guidelines:
|
||||
https://golang.org/doc/contribute.html
|
||||
|
||||
##### Please note that we do not use pull requests.
|
||||
|
||||
Unless otherwise noted, the Go source files are distributed
|
||||
under the BSD-style license found in the LICENSE file.
|
||||
|
||||
--
|
||||
|
||||
## Binary Distribution Notes
|
||||
|
||||
If you have just untarred a binary Go distribution, you need to set
|
||||
the environment variable $GOROOT to the full path of the go
|
||||
directory (the one containing this file). You can omit the
|
||||
variable if you unpack it into /usr/local/go, or if you rebuild
|
||||
from sources by running all.bash (see doc/install-source.html).
|
||||
You should also add the Go binary directory $GOROOT/bin
|
||||
to your shell's path.
|
||||
|
||||
For example, if you extracted the tar file into $HOME/go, you might
|
||||
put the following in your .profile:
|
||||
|
||||
export GOROOT=$HOME/go
|
||||
export PATH=$PATH:$GOROOT/bin
|
||||
|
||||
See https://golang.org/doc/install or doc/install.html for more details.
|
||||
390
api/next.txt
390
api/next.txt
@@ -1,249 +1,141 @@
|
||||
pkg debug/elf, const R_PPC64_ADDR14 = 7
|
||||
pkg debug/elf, const R_PPC64_ADDR14 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_ADDR14_BRNTAKEN = 9
|
||||
pkg debug/elf, const R_PPC64_ADDR14_BRNTAKEN R_PPC64
|
||||
pkg debug/elf, const R_PPC64_ADDR14_BRTAKEN = 8
|
||||
pkg debug/elf, const R_PPC64_ADDR14_BRTAKEN R_PPC64
|
||||
pkg debug/elf, const R_PPC64_ADDR16 = 3
|
||||
pkg debug/elf, const R_PPC64_ADDR16 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_ADDR16_DS = 56
|
||||
pkg debug/elf, const R_PPC64_ADDR16_DS R_PPC64
|
||||
pkg debug/elf, const R_PPC64_ADDR16_HA = 6
|
||||
pkg debug/elf, const R_PPC64_ADDR16_HA R_PPC64
|
||||
pkg debug/elf, const R_PPC64_ADDR16_HI = 5
|
||||
pkg debug/elf, const R_PPC64_ADDR16_HI R_PPC64
|
||||
pkg debug/elf, const R_PPC64_ADDR16_HIGHER = 39
|
||||
pkg debug/elf, const R_PPC64_ADDR16_HIGHER R_PPC64
|
||||
pkg debug/elf, const R_PPC64_ADDR16_HIGHERA = 40
|
||||
pkg debug/elf, const R_PPC64_ADDR16_HIGHERA R_PPC64
|
||||
pkg debug/elf, const R_PPC64_ADDR16_HIGHEST = 41
|
||||
pkg debug/elf, const R_PPC64_ADDR16_HIGHEST R_PPC64
|
||||
pkg debug/elf, const R_PPC64_ADDR16_HIGHESTA = 42
|
||||
pkg debug/elf, const R_PPC64_ADDR16_HIGHESTA R_PPC64
|
||||
pkg debug/elf, const R_PPC64_ADDR16_LO = 4
|
||||
pkg debug/elf, const R_PPC64_ADDR16_LO R_PPC64
|
||||
pkg debug/elf, const R_PPC64_ADDR16_LO_DS = 57
|
||||
pkg debug/elf, const R_PPC64_ADDR16_LO_DS R_PPC64
|
||||
pkg debug/elf, const R_PPC64_ADDR24 = 2
|
||||
pkg debug/elf, const R_PPC64_ADDR24 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_ADDR32 = 1
|
||||
pkg debug/elf, const R_PPC64_ADDR32 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_ADDR64 = 38
|
||||
pkg debug/elf, const R_PPC64_ADDR64 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_DTPMOD64 = 68
|
||||
pkg debug/elf, const R_PPC64_DTPMOD64 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_DTPREL16 = 74
|
||||
pkg debug/elf, const R_PPC64_DTPREL16 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_DS = 101
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_DS R_PPC64
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_HA = 77
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_HA R_PPC64
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_HI = 76
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_HI R_PPC64
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_HIGHER = 103
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_HIGHER R_PPC64
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_HIGHERA = 104
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_HIGHERA R_PPC64
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_HIGHEST = 105
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_HIGHEST R_PPC64
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_HIGHESTA = 106
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_HIGHESTA R_PPC64
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_LO = 75
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_LO R_PPC64
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_LO_DS = 102
|
||||
pkg debug/elf, const R_PPC64_DTPREL16_LO_DS R_PPC64
|
||||
pkg debug/elf, const R_PPC64_DTPREL64 = 78
|
||||
pkg debug/elf, const R_PPC64_DTPREL64 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT16 = 14
|
||||
pkg debug/elf, const R_PPC64_GOT16 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT16_DS = 58
|
||||
pkg debug/elf, const R_PPC64_GOT16_DS R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT16_HA = 17
|
||||
pkg debug/elf, const R_PPC64_GOT16_HA R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT16_HI = 16
|
||||
pkg debug/elf, const R_PPC64_GOT16_HI R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT16_LO = 15
|
||||
pkg debug/elf, const R_PPC64_GOT16_LO R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT16_LO_DS = 59
|
||||
pkg debug/elf, const R_PPC64_GOT16_LO_DS R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT_DTPREL16_DS = 91
|
||||
pkg debug/elf, const R_PPC64_GOT_DTPREL16_DS R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT_DTPREL16_HA = 94
|
||||
pkg debug/elf, const R_PPC64_GOT_DTPREL16_HA R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT_DTPREL16_HI = 93
|
||||
pkg debug/elf, const R_PPC64_GOT_DTPREL16_HI R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT_DTPREL16_LO_DS = 92
|
||||
pkg debug/elf, const R_PPC64_GOT_DTPREL16_LO_DS R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT_TLSGD16 = 79
|
||||
pkg debug/elf, const R_PPC64_GOT_TLSGD16 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT_TLSGD16_HA = 82
|
||||
pkg debug/elf, const R_PPC64_GOT_TLSGD16_HA R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT_TLSGD16_HI = 81
|
||||
pkg debug/elf, const R_PPC64_GOT_TLSGD16_HI R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT_TLSGD16_LO = 80
|
||||
pkg debug/elf, const R_PPC64_GOT_TLSGD16_LO R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT_TLSLD16 = 83
|
||||
pkg debug/elf, const R_PPC64_GOT_TLSLD16 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT_TLSLD16_HA = 86
|
||||
pkg debug/elf, const R_PPC64_GOT_TLSLD16_HA R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT_TLSLD16_HI = 85
|
||||
pkg debug/elf, const R_PPC64_GOT_TLSLD16_HI R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT_TLSLD16_LO = 84
|
||||
pkg debug/elf, const R_PPC64_GOT_TLSLD16_LO R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT_TPREL16_DS = 87
|
||||
pkg debug/elf, const R_PPC64_GOT_TPREL16_DS R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT_TPREL16_HA = 90
|
||||
pkg debug/elf, const R_PPC64_GOT_TPREL16_HA R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT_TPREL16_HI = 89
|
||||
pkg debug/elf, const R_PPC64_GOT_TPREL16_HI R_PPC64
|
||||
pkg debug/elf, const R_PPC64_GOT_TPREL16_LO_DS = 88
|
||||
pkg debug/elf, const R_PPC64_GOT_TPREL16_LO_DS R_PPC64
|
||||
pkg debug/elf, const R_PPC64_JMP_SLOT = 21
|
||||
pkg debug/elf, const R_PPC64_JMP_SLOT R_PPC64
|
||||
pkg debug/elf, const R_PPC64_NONE = 0
|
||||
pkg debug/elf, const R_PPC64_NONE R_PPC64
|
||||
pkg debug/elf, const R_PPC64_REL14 = 11
|
||||
pkg debug/elf, const R_PPC64_REL14 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_REL14_BRNTAKEN = 13
|
||||
pkg debug/elf, const R_PPC64_REL14_BRNTAKEN R_PPC64
|
||||
pkg debug/elf, const R_PPC64_REL14_BRTAKEN = 12
|
||||
pkg debug/elf, const R_PPC64_REL14_BRTAKEN R_PPC64
|
||||
pkg debug/elf, const R_PPC64_REL16 = 249
|
||||
pkg debug/elf, const R_PPC64_REL16 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_REL16_HA = 252
|
||||
pkg debug/elf, const R_PPC64_REL16_HA R_PPC64
|
||||
pkg debug/elf, const R_PPC64_REL16_HI = 251
|
||||
pkg debug/elf, const R_PPC64_REL16_HI R_PPC64
|
||||
pkg debug/elf, const R_PPC64_REL16_LO = 250
|
||||
pkg debug/elf, const R_PPC64_REL16_LO R_PPC64
|
||||
pkg debug/elf, const R_PPC64_REL24 = 10
|
||||
pkg debug/elf, const R_PPC64_REL24 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_REL32 = 26
|
||||
pkg debug/elf, const R_PPC64_REL32 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_REL64 = 44
|
||||
pkg debug/elf, const R_PPC64_REL64 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TLS = 67
|
||||
pkg debug/elf, const R_PPC64_TLS R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TLSGD = 107
|
||||
pkg debug/elf, const R_PPC64_TLSGD R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TLSLD = 108
|
||||
pkg debug/elf, const R_PPC64_TLSLD R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TOC = 51
|
||||
pkg debug/elf, const R_PPC64_TOC R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TOC16 = 47
|
||||
pkg debug/elf, const R_PPC64_TOC16 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TOC16_DS = 63
|
||||
pkg debug/elf, const R_PPC64_TOC16_DS R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TOC16_HA = 50
|
||||
pkg debug/elf, const R_PPC64_TOC16_HA R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TOC16_HI = 49
|
||||
pkg debug/elf, const R_PPC64_TOC16_HI R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TOC16_LO = 48
|
||||
pkg debug/elf, const R_PPC64_TOC16_LO R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TOC16_LO_DS = 64
|
||||
pkg debug/elf, const R_PPC64_TOC16_LO_DS R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TPREL16 = 69
|
||||
pkg debug/elf, const R_PPC64_TPREL16 R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TPREL16_DS = 95
|
||||
pkg debug/elf, const R_PPC64_TPREL16_DS R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TPREL16_HA = 72
|
||||
pkg debug/elf, const R_PPC64_TPREL16_HA R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TPREL16_HI = 71
|
||||
pkg debug/elf, const R_PPC64_TPREL16_HI R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TPREL16_HIGHER = 97
|
||||
pkg debug/elf, const R_PPC64_TPREL16_HIGHER R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TPREL16_HIGHERA = 98
|
||||
pkg debug/elf, const R_PPC64_TPREL16_HIGHERA R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TPREL16_HIGHEST = 99
|
||||
pkg debug/elf, const R_PPC64_TPREL16_HIGHEST R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TPREL16_HIGHESTA = 100
|
||||
pkg debug/elf, const R_PPC64_TPREL16_HIGHESTA R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TPREL16_LO = 70
|
||||
pkg debug/elf, const R_PPC64_TPREL16_LO R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TPREL16_LO_DS = 96
|
||||
pkg debug/elf, const R_PPC64_TPREL16_LO_DS R_PPC64
|
||||
pkg debug/elf, const R_PPC64_TPREL64 = 73
|
||||
pkg debug/elf, const R_PPC64_TPREL64 R_PPC64
|
||||
pkg debug/elf, method (R_PPC64) GoString() string
|
||||
pkg debug/elf, method (R_PPC64) String() string
|
||||
pkg debug/elf, type R_PPC64 int
|
||||
pkg runtime (openbsd-386), const CLOCK_MONOTONIC = 3
|
||||
pkg runtime (openbsd-386), const CLOCK_MONOTONIC ideal-int
|
||||
pkg runtime (openbsd-386), const CLOCK_PROF = 2
|
||||
pkg runtime (openbsd-386), const CLOCK_PROF ideal-int
|
||||
pkg runtime (openbsd-386), const CLOCK_REALTIME = 0
|
||||
pkg runtime (openbsd-386), const CLOCK_REALTIME ideal-int
|
||||
pkg runtime (openbsd-386), const CLOCK_VIRTUAL = 1
|
||||
pkg runtime (openbsd-386), const CLOCK_VIRTUAL ideal-int
|
||||
pkg runtime (openbsd-386), const CTL_HW = 6
|
||||
pkg runtime (openbsd-386), const CTL_HW ideal-int
|
||||
pkg runtime (openbsd-386), const EAGAIN = 35
|
||||
pkg runtime (openbsd-386), const EAGAIN ideal-int
|
||||
pkg runtime (openbsd-386), const ENOTSUP = 91
|
||||
pkg runtime (openbsd-386), const ENOTSUP ideal-int
|
||||
pkg runtime (openbsd-386), const ESRCH = 3
|
||||
pkg runtime (openbsd-386), const ESRCH ideal-int
|
||||
pkg runtime (openbsd-386), const EWOULDBLOCK = 35
|
||||
pkg runtime (openbsd-386), const EWOULDBLOCK ideal-int
|
||||
pkg runtime (openbsd-386), const HW_NCPU = 3
|
||||
pkg runtime (openbsd-386), const HW_NCPU ideal-int
|
||||
pkg runtime (openbsd-386-cgo), const CLOCK_MONOTONIC = 3
|
||||
pkg runtime (openbsd-386-cgo), const CLOCK_MONOTONIC ideal-int
|
||||
pkg runtime (openbsd-386-cgo), const CLOCK_PROF = 2
|
||||
pkg runtime (openbsd-386-cgo), const CLOCK_PROF ideal-int
|
||||
pkg runtime (openbsd-386-cgo), const CLOCK_REALTIME = 0
|
||||
pkg runtime (openbsd-386-cgo), const CLOCK_REALTIME ideal-int
|
||||
pkg runtime (openbsd-386-cgo), const CLOCK_VIRTUAL = 1
|
||||
pkg runtime (openbsd-386-cgo), const CLOCK_VIRTUAL ideal-int
|
||||
pkg runtime (openbsd-386-cgo), const CTL_HW = 6
|
||||
pkg runtime (openbsd-386-cgo), const CTL_HW ideal-int
|
||||
pkg runtime (openbsd-386-cgo), const EAGAIN = 35
|
||||
pkg runtime (openbsd-386-cgo), const EAGAIN ideal-int
|
||||
pkg runtime (openbsd-386-cgo), const ENOTSUP = 91
|
||||
pkg runtime (openbsd-386-cgo), const ENOTSUP ideal-int
|
||||
pkg runtime (openbsd-386-cgo), const ESRCH = 3
|
||||
pkg runtime (openbsd-386-cgo), const ESRCH ideal-int
|
||||
pkg runtime (openbsd-386-cgo), const EWOULDBLOCK = 35
|
||||
pkg runtime (openbsd-386-cgo), const EWOULDBLOCK ideal-int
|
||||
pkg runtime (openbsd-386-cgo), const HW_NCPU = 3
|
||||
pkg runtime (openbsd-386-cgo), const HW_NCPU ideal-int
|
||||
pkg runtime (openbsd-amd64), const CLOCK_MONOTONIC = 3
|
||||
pkg runtime (openbsd-amd64), const CLOCK_MONOTONIC ideal-int
|
||||
pkg runtime (openbsd-amd64), const CLOCK_PROF = 2
|
||||
pkg runtime (openbsd-amd64), const CLOCK_PROF ideal-int
|
||||
pkg runtime (openbsd-amd64), const CLOCK_REALTIME = 0
|
||||
pkg runtime (openbsd-amd64), const CLOCK_REALTIME ideal-int
|
||||
pkg runtime (openbsd-amd64), const CLOCK_VIRTUAL = 1
|
||||
pkg runtime (openbsd-amd64), const CLOCK_VIRTUAL ideal-int
|
||||
pkg runtime (openbsd-amd64), const CTL_HW = 6
|
||||
pkg runtime (openbsd-amd64), const CTL_HW ideal-int
|
||||
pkg runtime (openbsd-amd64), const EAGAIN = 35
|
||||
pkg runtime (openbsd-amd64), const EAGAIN ideal-int
|
||||
pkg runtime (openbsd-amd64), const ENOTSUP = 91
|
||||
pkg runtime (openbsd-amd64), const ENOTSUP ideal-int
|
||||
pkg runtime (openbsd-amd64), const ESRCH = 3
|
||||
pkg runtime (openbsd-amd64), const ESRCH ideal-int
|
||||
pkg runtime (openbsd-amd64), const EWOULDBLOCK = 35
|
||||
pkg runtime (openbsd-amd64), const EWOULDBLOCK ideal-int
|
||||
pkg runtime (openbsd-amd64), const HW_NCPU = 3
|
||||
pkg runtime (openbsd-amd64), const HW_NCPU ideal-int
|
||||
pkg runtime (openbsd-amd64-cgo), const CLOCK_MONOTONIC = 3
|
||||
pkg runtime (openbsd-amd64-cgo), const CLOCK_MONOTONIC ideal-int
|
||||
pkg runtime (openbsd-amd64-cgo), const CLOCK_PROF = 2
|
||||
pkg runtime (openbsd-amd64-cgo), const CLOCK_PROF ideal-int
|
||||
pkg runtime (openbsd-amd64-cgo), const CLOCK_REALTIME = 0
|
||||
pkg runtime (openbsd-amd64-cgo), const CLOCK_REALTIME ideal-int
|
||||
pkg runtime (openbsd-amd64-cgo), const CLOCK_VIRTUAL = 1
|
||||
pkg runtime (openbsd-amd64-cgo), const CLOCK_VIRTUAL ideal-int
|
||||
pkg runtime (openbsd-amd64-cgo), const CTL_HW = 6
|
||||
pkg runtime (openbsd-amd64-cgo), const CTL_HW ideal-int
|
||||
pkg runtime (openbsd-amd64-cgo), const EAGAIN = 35
|
||||
pkg runtime (openbsd-amd64-cgo), const EAGAIN ideal-int
|
||||
pkg runtime (openbsd-amd64-cgo), const ENOTSUP = 91
|
||||
pkg runtime (openbsd-amd64-cgo), const ENOTSUP ideal-int
|
||||
pkg runtime (openbsd-amd64-cgo), const ESRCH = 3
|
||||
pkg runtime (openbsd-amd64-cgo), const ESRCH ideal-int
|
||||
pkg runtime (openbsd-amd64-cgo), const EWOULDBLOCK = 35
|
||||
pkg runtime (openbsd-amd64-cgo), const EWOULDBLOCK ideal-int
|
||||
pkg runtime (openbsd-amd64-cgo), const HW_NCPU = 3
|
||||
pkg runtime (openbsd-amd64-cgo), const HW_NCPU ideal-int
|
||||
pkg debug/goobj, const SBSS = 21
|
||||
pkg debug/goobj, const SBSS SymKind
|
||||
pkg debug/goobj, const SCONST = 31
|
||||
pkg debug/goobj, const SCONST SymKind
|
||||
pkg debug/goobj, const SDATA = 19
|
||||
pkg debug/goobj, const SDATA SymKind
|
||||
pkg debug/goobj, const SDYNIMPORT = 32
|
||||
pkg debug/goobj, const SDYNIMPORT SymKind
|
||||
pkg debug/goobj, const SELFROSECT = 12
|
||||
pkg debug/goobj, const SELFROSECT SymKind
|
||||
pkg debug/goobj, const SELFRXSECT = 2
|
||||
pkg debug/goobj, const SELFRXSECT SymKind
|
||||
pkg debug/goobj, const SELFSECT = 14
|
||||
pkg debug/goobj, const SELFSECT SymKind
|
||||
pkg debug/goobj, const SFILE = 29
|
||||
pkg debug/goobj, const SFILE SymKind
|
||||
pkg debug/goobj, const SFILEPATH = 30
|
||||
pkg debug/goobj, const SFILEPATH SymKind
|
||||
pkg debug/goobj, const SFUNCTAB = 8
|
||||
pkg debug/goobj, const SFUNCTAB SymKind
|
||||
pkg debug/goobj, const SGOFUNC = 6
|
||||
pkg debug/goobj, const SGOFUNC SymKind
|
||||
pkg debug/goobj, const SGOSTRING = 5
|
||||
pkg debug/goobj, const SGOSTRING SymKind
|
||||
pkg debug/goobj, const SHOSTOBJ = 33
|
||||
pkg debug/goobj, const SHOSTOBJ SymKind
|
||||
pkg debug/goobj, const SINITARR = 18
|
||||
pkg debug/goobj, const SINITARR SymKind
|
||||
pkg debug/goobj, const SMACHO = 15
|
||||
pkg debug/goobj, const SMACHO SymKind
|
||||
pkg debug/goobj, const SMACHOGOT = 16
|
||||
pkg debug/goobj, const SMACHOGOT SymKind
|
||||
pkg debug/goobj, const SMACHOINDIRECTGOT = 28
|
||||
pkg debug/goobj, const SMACHOINDIRECTGOT SymKind
|
||||
pkg debug/goobj, const SMACHOINDIRECTPLT = 27
|
||||
pkg debug/goobj, const SMACHOINDIRECTPLT SymKind
|
||||
pkg debug/goobj, const SMACHOPLT = 13
|
||||
pkg debug/goobj, const SMACHOPLT SymKind
|
||||
pkg debug/goobj, const SMACHOSYMSTR = 25
|
||||
pkg debug/goobj, const SMACHOSYMSTR SymKind
|
||||
pkg debug/goobj, const SMACHOSYMTAB = 26
|
||||
pkg debug/goobj, const SMACHOSYMTAB SymKind
|
||||
pkg debug/goobj, const SNOPTRBSS = 22
|
||||
pkg debug/goobj, const SNOPTRBSS SymKind
|
||||
pkg debug/goobj, const SNOPTRDATA = 17
|
||||
pkg debug/goobj, const SNOPTRDATA SymKind
|
||||
pkg debug/goobj, const SPCLNTAB = 11
|
||||
pkg debug/goobj, const SPCLNTAB SymKind
|
||||
pkg debug/goobj, const SRODATA = 7
|
||||
pkg debug/goobj, const SRODATA SymKind
|
||||
pkg debug/goobj, const SSTRING = 4
|
||||
pkg debug/goobj, const SSTRING SymKind
|
||||
pkg debug/goobj, const SSYMTAB = 10
|
||||
pkg debug/goobj, const SSYMTAB SymKind
|
||||
pkg debug/goobj, const STEXT = 1
|
||||
pkg debug/goobj, const STEXT SymKind
|
||||
pkg debug/goobj, const STLSBSS = 23
|
||||
pkg debug/goobj, const STLSBSS SymKind
|
||||
pkg debug/goobj, const STYPE = 3
|
||||
pkg debug/goobj, const STYPE SymKind
|
||||
pkg debug/goobj, const STYPELINK = 9
|
||||
pkg debug/goobj, const STYPELINK SymKind
|
||||
pkg debug/goobj, const SWINDOWS = 20
|
||||
pkg debug/goobj, const SWINDOWS SymKind
|
||||
pkg debug/goobj, const SXREF = 24
|
||||
pkg debug/goobj, const SXREF SymKind
|
||||
pkg debug/goobj, func Parse(io.ReadSeeker, string) (*Package, error)
|
||||
pkg debug/goobj, method (Sym) String() string
|
||||
pkg debug/goobj, method (SymID) String() string
|
||||
pkg debug/goobj, method (SymKind) String() string
|
||||
pkg debug/goobj, type Data struct
|
||||
pkg debug/goobj, type Data struct, Offset int64
|
||||
pkg debug/goobj, type Data struct, Size int64
|
||||
pkg debug/goobj, type Func struct
|
||||
pkg debug/goobj, type Func struct, Args int
|
||||
pkg debug/goobj, type Func struct, File []string
|
||||
pkg debug/goobj, type Func struct, Frame int
|
||||
pkg debug/goobj, type Func struct, FuncData []FuncData
|
||||
pkg debug/goobj, type Func struct, Leaf bool
|
||||
pkg debug/goobj, type Func struct, NoSplit bool
|
||||
pkg debug/goobj, type Func struct, PCData []Data
|
||||
pkg debug/goobj, type Func struct, PCFile Data
|
||||
pkg debug/goobj, type Func struct, PCLine Data
|
||||
pkg debug/goobj, type Func struct, PCSP Data
|
||||
pkg debug/goobj, type Func struct, Var []Var
|
||||
pkg debug/goobj, type FuncData struct
|
||||
pkg debug/goobj, type FuncData struct, Offset int64
|
||||
pkg debug/goobj, type FuncData struct, Sym SymID
|
||||
pkg debug/goobj, type Package struct
|
||||
pkg debug/goobj, type Package struct, ImportPath string
|
||||
pkg debug/goobj, type Package struct, Imports []string
|
||||
pkg debug/goobj, type Package struct, MaxVersion int
|
||||
pkg debug/goobj, type Package struct, Syms []*Sym
|
||||
pkg debug/goobj, type Reloc struct
|
||||
pkg debug/goobj, type Reloc struct, Add int
|
||||
pkg debug/goobj, type Reloc struct, Offset int
|
||||
pkg debug/goobj, type Reloc struct, Size int
|
||||
pkg debug/goobj, type Reloc struct, Sym SymID
|
||||
pkg debug/goobj, type Reloc struct, Type int
|
||||
pkg debug/goobj, type Sym struct
|
||||
pkg debug/goobj, type Sym struct, Data Data
|
||||
pkg debug/goobj, type Sym struct, DupOK bool
|
||||
pkg debug/goobj, type Sym struct, Func *Func
|
||||
pkg debug/goobj, type Sym struct, Kind SymKind
|
||||
pkg debug/goobj, type Sym struct, Reloc []Reloc
|
||||
pkg debug/goobj, type Sym struct, Size int
|
||||
pkg debug/goobj, type Sym struct, Type SymID
|
||||
pkg debug/goobj, type Sym struct, embedded SymID
|
||||
pkg debug/goobj, type SymID struct
|
||||
pkg debug/goobj, type SymID struct, Name string
|
||||
pkg debug/goobj, type SymID struct, Version int
|
||||
pkg debug/goobj, type SymKind int
|
||||
pkg debug/goobj, type Var struct
|
||||
pkg debug/goobj, type Var struct, Kind int
|
||||
pkg debug/goobj, type Var struct, Name string
|
||||
pkg debug/goobj, type Var struct, Offset int
|
||||
pkg debug/goobj, type Var struct, Type SymID
|
||||
pkg unicode, const Version = "7.0.0"
|
||||
pkg unicode, var Bassa_Vah *RangeTable
|
||||
pkg unicode, var Caucasian_Albanian *RangeTable
|
||||
pkg unicode, var Duployan *RangeTable
|
||||
pkg unicode, var Elbasan *RangeTable
|
||||
pkg unicode, var Grantha *RangeTable
|
||||
pkg unicode, var Khojki *RangeTable
|
||||
pkg unicode, var Khudawadi *RangeTable
|
||||
pkg unicode, var Linear_A *RangeTable
|
||||
pkg unicode, var Mahajani *RangeTable
|
||||
pkg unicode, var Manichaean *RangeTable
|
||||
pkg unicode, var Mende_Kikakui *RangeTable
|
||||
pkg unicode, var Modi *RangeTable
|
||||
pkg unicode, var Mro *RangeTable
|
||||
pkg unicode, var Nabataean *RangeTable
|
||||
pkg unicode, var Old_North_Arabian *RangeTable
|
||||
pkg unicode, var Old_Permic *RangeTable
|
||||
pkg unicode, var Pahawh_Hmong *RangeTable
|
||||
pkg unicode, var Palmyrene *RangeTable
|
||||
pkg unicode, var Pau_Cin_Hau *RangeTable
|
||||
pkg unicode, var Psalter_Pahlavi *RangeTable
|
||||
pkg unicode, var Siddham *RangeTable
|
||||
pkg unicode, var Tirhuta *RangeTable
|
||||
pkg unicode, var Warang_Citi *RangeTable
|
||||
|
||||
@@ -350,11 +350,7 @@ live pointers in its arguments, results, and local stack frame.
|
||||
For an assembly function with no pointer results and
|
||||
either no local stack frame or no function calls,
|
||||
the only requirement is to define a Go prototype for the function
|
||||
in a Go source file in the same package. The name of the assembly
|
||||
function must not contain the package name component (for example,
|
||||
function <code>Syscall</code> in package <code>syscall</code> should
|
||||
use the name <code>·Syscall</code> instead of the equivalent name
|
||||
<code>syscall·Syscall</code> in its <code>TEXT</code> directive).
|
||||
in a Go source file in the same package.
|
||||
For more complex situations, explicit annotation is needed.
|
||||
These annotations use pseudo-instructions defined in the standard
|
||||
<code>#include</code> file <code>funcdata.h</code>.
|
||||
|
||||
@@ -108,14 +108,13 @@ when developing Go code.
|
||||
<p>
|
||||
To get started, create a workspace directory and set <code>GOPATH</code>
|
||||
accordingly. Your workspace can be located wherever you like, but we'll use
|
||||
<code>$HOME/work</code> in this document. Note that this must <b>not</b> be the
|
||||
<code>$HOME/go</code> in this document. Note that this must <b>not</b> be the
|
||||
same path as your Go installation.
|
||||
(Another common setup is to set <code>GOPATH=$HOME</code>.)
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ <b>mkdir $HOME/work</b>
|
||||
$ <b>export GOPATH=$HOME/work</b>
|
||||
$ <b>mkdir $HOME/go</b>
|
||||
$ <b>export GOPATH=$HOME/go</b>
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
@@ -127,11 +126,6 @@ to your <code>PATH</code>:
|
||||
$ <b>export PATH=$PATH:$GOPATH/bin</b>
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
To learn more about setting up the <code>GOPATH</code> environment variable,
|
||||
please see
|
||||
<a href="/cmd/go/#hdr-GOPATH_environment_variable"><code>go help gopath</code></a>
|
||||
</p>
|
||||
|
||||
<h3 id="PackagePaths">Package paths</h3>
|
||||
|
||||
@@ -224,7 +218,7 @@ 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/work/bin/hello</code>.
|
||||
<code>$HOME/go/bin/hello</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -260,7 +254,7 @@ optional: you do not need to use source control to write Go code.
|
||||
<pre>
|
||||
$ <b>cd $GOPATH/src/github.com/user/hello</b>
|
||||
$ <b>git init</b>
|
||||
Initialized empty Git repository in /home/user/work/src/github.com/user/hello/.git/
|
||||
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
|
||||
|
||||
@@ -8,8 +8,8 @@ The <a href="//golang.org/change">change log</a> has the full details.</p>
|
||||
<p>To update to a specific release, use:</p>
|
||||
|
||||
<pre>
|
||||
git pull
|
||||
git checkout <i>release-branch</i>
|
||||
hg pull
|
||||
hg update <i>tag</i>
|
||||
</pre>
|
||||
|
||||
<h2 id="go1.4">go1.4 (released 2014/12/10)</h2>
|
||||
|
||||
@@ -40,7 +40,7 @@ is mirrored to the <code>gcc/go/gofrontend</code> directory in the GCC
|
||||
repository, and the <code>gofrontend</code> <code>libgo</code>
|
||||
directory is mirrored to the GCC <code>libgo</code> directory. In
|
||||
addition, the <code>test</code> directory
|
||||
from <a href="//go.googlesource.com/go">the main Go repository</a>
|
||||
from <a href="//code.google.com/p/go">the main Go repository</a>
|
||||
is mirrored to the <code>gcc/testsuite/go.test/test</code> directory
|
||||
in the GCC repository.
|
||||
</p>
|
||||
@@ -65,7 +65,7 @@ from <code>gcc/go/gofrontend</code> to <code>gcc/go</code>.
|
||||
|
||||
<p>
|
||||
The run-time library for gccgo is mostly the same as the library
|
||||
in <a href="//go.googlesource.com/go">the main Go repository</a>.
|
||||
in <a href="//code.google.com/p/go">the main Go repository</a>.
|
||||
The library code in the Go repository is periodically merged into
|
||||
the <code>libgo/go</code> directory of the <code>gofrontend</code> and
|
||||
then the GCC repositories, using the shell
|
||||
@@ -105,7 +105,7 @@ or <code>gcc/testsuite/go.dg</code> directories in the GCC repository.
|
||||
<p>
|
||||
Changes to the Go frontend should follow the same process as for the
|
||||
main Go repository, only for the <code>gofrontend</code> project and
|
||||
the <code>gofrontend-dev@googlegroups.com</code> mailing list
|
||||
the<code>gofrontend-dev@googlegroups.com</code> mailing list
|
||||
rather than the <code>go</code> project and the
|
||||
<code>golang-dev@googlegroups.com</code> mailing list. Those changes
|
||||
will then be merged into the GCC sources.
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
Overall:
|
||||
|
||||
build: Go 1.4 required to build (https://golang.org/cl/2470, https://golang.org/cl/2993)
|
||||
|
||||
New Ports:
|
||||
Darwin/ARM, a.k.a iOS. (https://golang.org/cl/2118, 2119, 3273, 2121, 2122, ..., 2127)
|
||||
|
||||
API additions and behavior changes:
|
||||
|
||||
bufio: add Reader.Discard (https://golang.org/cl/2260)
|
||||
crypto/cipher: clarify what will happen if len(src) != len(dst) for the Stream interface. (https://golang.org/cl/1754)
|
||||
crypto/elliptic: add Name field to CurveParams struct (https://golang.org/cl/2133)
|
||||
crypto/tls: change default minimum version to TLS 1.0. (https://golang.org/cl/1791)
|
||||
encoding/base64: add unpadded encodings (https://golang.org/cl/1511)
|
||||
log: add SetOutput functions (https://golang.org/cl/2686, https://golang.org/cl/3023)
|
||||
net/http: support for setting trailers from a server Handler (https://golang.org/cl/2157)
|
||||
net/http/cgi: fix REMOTE_ADDR, REMOTE_HOST, add REMOTE_PORT (https://golang.org/cl/4933)
|
||||
net/smtp: add TLSConnectionState accessor (https://golang.org/cl/2151)
|
||||
os/signal: add Ignore and Reset (https://golang.org/cl/3580)
|
||||
runtime, syscall: use SYSCALL instruction on FreeBSD (Go 1.5 now requires FreeBSD 8-STABLE+) (https://golang.org/cl/3020)
|
||||
strings: add Compare(x, y string) int, for symmetry with bytes.Compare (https://golang.org/cl/2828)
|
||||
testing/quick: support generation of arrays (https://golang.org/cl/3865)
|
||||
|
||||
Tools:
|
||||
|
||||
cmd/go: std wildcard now excludes commands in main repo (https://golang.org/cl/5550)
|
||||
cmd/vet: better validation of struct tags (https://golang.org/cl/2685)
|
||||
cmd/ld: no longer record build timestamp in Windows PE file header (https://golang.org/cl/3740)
|
||||
|
||||
Performance:
|
||||
|
||||
cmd/gc: optimize memclr of slices and arrays (https://golang.org/cl/2520)
|
||||
sort: number of Sort performance optimizations (https://golang.org/cl/2100, https://golang.org/cl/2614, ...)
|
||||
strconv: optimize decimal to string conversion (https://golang.org/cl/2105)
|
||||
math/big: faster assembly kernels for amd64 and 386 (https://golang.org/cl/2503, https://golang.org/cl/2560)
|
||||
math/big: faster "pure Go" kernels for platforms w/o assembly kernels (https://golang.org/cl/2480)
|
||||
|
||||
Assembler:
|
||||
|
||||
ARM assembly syntax has had some features removed.
|
||||
|
||||
- mentioning SP or PC as a hardware register
|
||||
These are always pseudo-registers except that in some contexts
|
||||
they're not, and it's confusing because the context should not affect
|
||||
which register you mean. Change the references to the hardware
|
||||
registers to be explicit: R13 for SP, R15 for PC.
|
||||
- constant creation using assignment
|
||||
The files say a=b when they could instead say #define a b.
|
||||
There is no reason to have both mechanisms.
|
||||
- R(0) to refer to R0.
|
||||
Some macros use this to a great extent. Again, it's easy just to
|
||||
use a #define to rename a register.
|
||||
|
||||
Also expression evaluation now uses uint64s instead of signed integers and the
|
||||
precedence of operators is now Go-like rather than C-like.
|
||||
@@ -228,7 +228,7 @@ document server running in a production configuration on
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Other examples include the <a href="//github.com/youtube/vitess/">Vitess</a>
|
||||
Other examples include the <a href="//code.google.com/p/vitess/">Vitess</a>
|
||||
system for large-scale SQL installations and Google's download server, <code>dl.google.com</code>,
|
||||
which delivers Chrome binaries and other large installables such as <code>apt-get</code>
|
||||
packages.
|
||||
@@ -260,7 +260,7 @@ Does Go support Google's protocol buffers?</h3>
|
||||
<p>
|
||||
A separate open source project provides the necessary compiler plugin and library.
|
||||
It is available at
|
||||
<a href="//github.com/golang/protobuf">github.com/golang/protobuf/</a>
|
||||
<a href="//code.google.com/p/goprotobuf/">code.google.com/p/goprotobuf/</a>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!--{
|
||||
"Title": "The Go Programming Language Specification",
|
||||
"Subtitle": "Version of December 26, 2014",
|
||||
"Subtitle": "Version of November 11, 2014",
|
||||
"Path": "/ref/spec"
|
||||
}-->
|
||||
|
||||
@@ -1981,7 +1981,7 @@ with no explicit type.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
var d = math.Sin(0.5) // d is float64
|
||||
var d = math.Sin(0.5) // d is int64
|
||||
var i = 42 // i is int
|
||||
var t, ok = x.(T) // t is T, ok is bool
|
||||
var n = nil // illegal
|
||||
@@ -5455,7 +5455,7 @@ const (
|
||||
c2 = len([10]float64{2}) // [10]float64{2} contains no function calls
|
||||
c3 = len([10]float64{c1}) // [10]float64{c1} contains no function calls
|
||||
c4 = len([10]float64{imag(2i)}) // imag(2i) is a constant and no function call is issued
|
||||
c5 = len([10]float64{imag(z)}) // invalid: imag(z) is a (non-constant) function call
|
||||
c5 = len([10]float64{imag(z)}) // invalid: imag(x) is a (non-constant) function call
|
||||
)
|
||||
var z complex128
|
||||
</pre>
|
||||
@@ -5579,7 +5579,7 @@ s3 := append(s2, s0...) // append a slice s3 == []int{0,
|
||||
s4 := append(s3[3:6], s3[2:]...) // append overlapping slice s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0}
|
||||
|
||||
var t []interface{}
|
||||
t = append(t, 42, 3.1415, "foo") // t == []interface{}{42, 3.1415, "foo"}
|
||||
t = append(t, 42, 3.1415, "foo") t == []interface{}{42, 3.1415, "foo"}
|
||||
|
||||
var b []byte
|
||||
b = append(b, "bar"...) // append string contents b == []byte{'b', 'a', 'r' }
|
||||
|
||||
@@ -77,25 +77,12 @@ The full set of supported combinations is listed in the discussion of
|
||||
|
||||
</div>
|
||||
|
||||
<h2 id="go14">Install Go compiler binaries</h2>
|
||||
<h2 id="ctools">Install C tools, if needed</h2>
|
||||
|
||||
<p>
|
||||
The Go tool chain is written in Go. To build it, you need a Go compiler installed.
|
||||
The scripts that do the initial build of the tools look for an existing Go tool
|
||||
chain in <code>$HOME/go1.4</code>.
|
||||
(This path may be overridden by setting the <code>GOROOT_BOOTSTRAP</code>
|
||||
environment variable.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Build the tools with Go version 1.4 or a point release (1.4.1, 1.4.2 etc.).
|
||||
Go 1.4 binaries can be found at <a href="/dl/">the downloads page</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Download the zip or tarball of Go 1.4 for your platform and extract it to
|
||||
<code>$HOME/go1.4</code> (or your nominated <code>GOROOT_BOOTSTRAP</code>
|
||||
location).
|
||||
The Go tool chain is written in C. To build it, you need a C compiler installed.
|
||||
Please refer to the <a href="//golang.org/wiki/InstallFromSource#install-c-tools">InstallFromSource</a>
|
||||
page on the Go community Wiki for operating system specific instructions.
|
||||
</p>
|
||||
|
||||
<h2 id="git">Install Git, if needed</h2>
|
||||
@@ -122,7 +109,7 @@ Then clone the repository and check out the latest release tag:</p>
|
||||
<pre>
|
||||
$ git clone https://go.googlesource.com/go
|
||||
$ cd go
|
||||
$ git checkout go1.4
|
||||
$ git checkout go1.4.1
|
||||
</pre>
|
||||
|
||||
<h2 id="head">(Optional) Switch to the master branch</h2>
|
||||
|
||||
@@ -14,10 +14,9 @@
|
||||
|
||||
<p>
|
||||
<a href="https://golang.org/dl/" target="_blank">Official binary
|
||||
distributions</a> are available for the FreeBSD (release 8-STABLE and above),
|
||||
Linux, Mac OS X (Snow Leopard and above), and Windows operating systems and
|
||||
the 32-bit (<code>386</code>) and 64-bit (<code>amd64</code>) x86 processor
|
||||
architectures.
|
||||
distributions</a> are available for the FreeBSD (release 8 and above), Linux, Mac OS X (Snow Leopard
|
||||
and above), and Windows operating systems and the 32-bit (<code>386</code>) and
|
||||
64-bit (<code>amd64</code>) x86 processor architectures.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -45,7 +44,7 @@ proceeding. If your OS or architecture is not on the list, it's possible that
|
||||
<th align="center">Notes</th>
|
||||
</tr>
|
||||
<tr><td colspan="3"><hr></td></tr>
|
||||
<tr><td>FreeBSD 8-STABLE or later</td> <td>amd64, 386, arm</td> <td>Debian GNU/kFreeBSD not supported; FreeBSD/ARM needs FreeBSD 10 or later</td></tr>
|
||||
<tr><td>FreeBSD 8 or later</td> <td>amd64, 386, arm</td> <td>Debian GNU/kFreeBSD not supported; FreeBSD/ARM needs FreeBSD 10 or later</td></tr>
|
||||
<tr><td>Linux 2.6.23 or later with glibc</td> <td>amd64, 386, arm</td> <td>CentOS/RHEL 5.x not supported; no binary distribution for ARM yet</td></tr>
|
||||
<tr><td>Mac OS X 10.6 or later</td> <td>amd64, 386</td> <td>use the gcc<sup>†</sup> that comes with Xcode<sup>‡</sup></td></tr>
|
||||
<tr><td>Windows XP or later</td> <td>amd64, 386</td> <td>use MinGW gcc<sup>†</sup>. No need for cygwin or msys.</td></tr>
|
||||
|
||||
BIN
doc/logo-153x55.png
Normal file
BIN
doc/logo-153x55.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
@@ -3,9 +3,9 @@
|
||||
// (the nodes are the data).
|
||||
// http://en.wikipedia.org/wiki/Peano_axioms
|
||||
|
||||
// This program demonstrates that Go's automatic
|
||||
// stack management can handle heavily recursive
|
||||
// computations.
|
||||
// This program demonstrates the power of Go's
|
||||
// segmented stacks when doing massively
|
||||
// recursive computations.
|
||||
|
||||
package main
|
||||
|
||||
|
||||
BIN
doc/sieve.gif
Normal file
BIN
doc/sieve.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@@ -292,8 +292,6 @@ extern char* getgoversion(void);
|
||||
extern char* getgoarm(void);
|
||||
extern char* getgo386(void);
|
||||
extern char* getgoextlinkenabled(void);
|
||||
extern char* getgohostos(void);
|
||||
extern char* getgohostarch(void);
|
||||
|
||||
extern char* mktempdir(void);
|
||||
extern void removeall(char*);
|
||||
@@ -312,15 +310,24 @@ extern void flagprint(int);
|
||||
#ifdef _WIN32
|
||||
|
||||
#if !defined(_WIN64) && !defined(__MINGW64_VERSION_MAJOR)
|
||||
struct timespec {
|
||||
int tv_sec;
|
||||
long tv_nsec;
|
||||
};
|
||||
#define execv(prog, argv) execv(prog, (const char* const*)(argv))
|
||||
#define execvp(prog, argv) execvp(prog, (const char**)(argv))
|
||||
#endif
|
||||
|
||||
extern int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
|
||||
extern int fork(void);
|
||||
extern int pread(int fd, void *buf, int n, int off);
|
||||
extern int pwrite(int fd, void *buf, int n, int off);
|
||||
#undef getwd
|
||||
#define getwd(s, ns) getcwd(s, ns)
|
||||
#undef lseek
|
||||
#define lseek(fd, n, base) _lseeki64(fd, n, base)
|
||||
#define mkdir(path, perm) mkdir(path)
|
||||
#define pipe(fd) _pipe(fd, 512, O_BINARY)
|
||||
#else
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
308
include/link.h
308
include/link.h
@@ -43,156 +43,32 @@ typedef struct Pcln Pcln;
|
||||
typedef struct Pcdata Pcdata;
|
||||
typedef struct Pciter Pciter;
|
||||
|
||||
// An Addr is an argument to an instruction.
|
||||
// The general forms and their encodings are:
|
||||
//
|
||||
// sym±offset(symkind)(reg)(index*scale)
|
||||
// Memory reference at address &sym(symkind) + offset + reg + index*scale.
|
||||
// Any of sym(symkind), ±offset, (reg), (index*scale), and *scale can be omitted.
|
||||
// If (reg) and *scale are both omitted, the resulting expression (index) is parsed as (reg).
|
||||
// To force a parsing as index*scale, write (index*1).
|
||||
// Encoding:
|
||||
// type = TYPE_MEM
|
||||
// name = symkind (NAME_AUTO, ...) or 0 (NAME_NONE)
|
||||
// sym = sym
|
||||
// offset = ±offset
|
||||
// reg = reg (REG_*)
|
||||
// index = index (REG_*)
|
||||
// scale = scale (1, 2, 4, 8)
|
||||
//
|
||||
// $<mem>
|
||||
// Effective address of memory reference <mem>, defined above.
|
||||
// Encoding: same as memory reference, but type = TYPE_ADDR.
|
||||
//
|
||||
// $<±integer value>
|
||||
// This is a special case of $<mem>, in which only ±offset is present.
|
||||
// It has a separate type for easy recognition.
|
||||
// Encoding:
|
||||
// type = TYPE_CONST
|
||||
// offset = ±integer value
|
||||
//
|
||||
// *<mem>
|
||||
// Indirect reference through memory reference <mem>, defined above.
|
||||
// Only used on x86 for CALL/JMP *sym(SB), which calls/jumps to a function
|
||||
// pointer stored in the data word sym(SB), not a function named sym(SB).
|
||||
// Encoding: same as above, but type = TYPE_INDIR.
|
||||
//
|
||||
// $*$<mem>
|
||||
// No longer used.
|
||||
// On machines with actual SB registers, $*$<mem> forced the
|
||||
// instruction encoding to use a full 32-bit constant, never a
|
||||
// reference relative to SB.
|
||||
//
|
||||
// $<floating point literal>
|
||||
// Floating point constant value.
|
||||
// Encoding:
|
||||
// type = TYPE_FCONST
|
||||
// u.dval = floating point value
|
||||
//
|
||||
// $<string literal, up to 8 chars>
|
||||
// String literal value (raw bytes used for DATA instruction).
|
||||
// Encoding:
|
||||
// type = TYPE_SCONST
|
||||
// u.sval = string
|
||||
//
|
||||
// <register name>
|
||||
// Any register: integer, floating point, control, segment, and so on.
|
||||
// If looking for specific register kind, must check type and reg value range.
|
||||
// Encoding:
|
||||
// type = TYPE_REG
|
||||
// reg = reg (REG_*)
|
||||
//
|
||||
// x(PC)
|
||||
// Encoding:
|
||||
// type = TYPE_BRANCH
|
||||
// u.branch = Prog* reference OR ELSE offset = target pc (branch takes priority)
|
||||
//
|
||||
// $±x-±y
|
||||
// Final argument to TEXT, specifying local frame size x and argument size y.
|
||||
// In this form, x and y are integer literals only, not arbitrary expressions.
|
||||
// This avoids parsing ambiguities due to the use of - as a separator.
|
||||
// The ± are optional.
|
||||
// If the final argument to TEXT omits the -±y, the encoding should still
|
||||
// use TYPE_TEXTSIZE (not TYPE_CONST), with u.argsize = ArgsSizeUnknown.
|
||||
// Encoding:
|
||||
// type = TYPE_TEXTSIZE
|
||||
// offset = x
|
||||
// u.argsize = y
|
||||
//
|
||||
// reg<<shift, reg>>shift, reg->shift, reg@>shift
|
||||
// Shifted register value, for ARM.
|
||||
// In this form, reg must be a register and shift can be a register or an integer constant.
|
||||
// Encoding:
|
||||
// type = TYPE_SHIFT
|
||||
// offset = (reg&15) | shifttype<<5 | count
|
||||
// shifttype = 0, 1, 2, 3 for <<, >>, ->, @>
|
||||
// count = (reg&15)<<8 | 1<<4 for a register shift count, (n&31)<<7 for an integer constant.
|
||||
//
|
||||
// (reg, reg)
|
||||
// A destination register pair. When used as the last argument of an instruction,
|
||||
// this form makes clear that both registers are destinations.
|
||||
// Encoding:
|
||||
// type = TYPE_REGREG
|
||||
// reg = first register
|
||||
// offset = second register
|
||||
//
|
||||
// reg, reg
|
||||
// TYPE_REGREG2, to be removed.
|
||||
//
|
||||
// prevent incompatible type signatures between liblink and 8l on Plan 9
|
||||
#pragma incomplete struct Node
|
||||
|
||||
struct Addr
|
||||
{
|
||||
int16 type; // could be int8
|
||||
int16 reg;
|
||||
int16 index;
|
||||
int8 scale;
|
||||
int8 name;
|
||||
int64 offset;
|
||||
LSym* sym;
|
||||
|
||||
vlong offset;
|
||||
|
||||
union
|
||||
{
|
||||
char sval[8];
|
||||
float64 dval;
|
||||
Prog* branch;
|
||||
int32 argsize; // for 5l, 8l
|
||||
uint64 bits; // raw union bits, for testing if anything has been written to any field
|
||||
Prog* branch; // for 5g, 6g, 8g
|
||||
} u;
|
||||
|
||||
// gotype is the name of the Go type descriptor for sym.
|
||||
// It cannot be set using assembly syntax.
|
||||
// It is generated by the Go compiler for global declarations,
|
||||
// to convey information about pointer locations to the back end
|
||||
// and for use in generating debug information.
|
||||
LSym* sym;
|
||||
LSym* gotype;
|
||||
|
||||
int8 class; // for internal use by liblink
|
||||
uint8 etype; // for internal use by 5g, 6g, 8g
|
||||
void* node; // for internal use by 5g, 6g, 8g
|
||||
int64 width; // for internal use by 5g, 6g, 8g
|
||||
};
|
||||
|
||||
enum {
|
||||
NAME_NONE = 0,
|
||||
NAME_EXTERN,
|
||||
NAME_STATIC,
|
||||
NAME_AUTO,
|
||||
NAME_PARAM,
|
||||
};
|
||||
|
||||
enum {
|
||||
TYPE_NONE = 0,
|
||||
TYPE_BRANCH = 5, // avoid accidental conflicts with NAME_*
|
||||
TYPE_TEXTSIZE,
|
||||
TYPE_MEM,
|
||||
TYPE_CONST,
|
||||
TYPE_FCONST,
|
||||
TYPE_SCONST,
|
||||
TYPE_REG,
|
||||
TYPE_ADDR,
|
||||
TYPE_SHIFT,
|
||||
TYPE_REGREG,
|
||||
TYPE_REGREG2,
|
||||
TYPE_INDIR,
|
||||
short type;
|
||||
uint8 index;
|
||||
int8 scale;
|
||||
int8 reg; // for 5l
|
||||
int8 name; // for 5l
|
||||
int8 class; // for 5l
|
||||
uint8 etype; // for 5g, 6g, 8g
|
||||
int32 offset2; // for 5l, 8l
|
||||
struct Node* node; // for 5g, 6g, 8g
|
||||
int64 width; // for 5g, 6g, 8g
|
||||
};
|
||||
|
||||
struct Reloc
|
||||
@@ -201,86 +77,45 @@ struct Reloc
|
||||
uchar siz;
|
||||
uchar done;
|
||||
int32 type;
|
||||
int32 variant; // RV_*: variant on computed value
|
||||
int64 add;
|
||||
int64 xadd;
|
||||
LSym* sym;
|
||||
LSym* xsym;
|
||||
};
|
||||
|
||||
// TODO(rsc): Describe prog.
|
||||
// TODO(rsc): Describe TEXT/GLOBL flag in from3, DATA width in from3.
|
||||
struct Prog
|
||||
{
|
||||
vlong pc;
|
||||
int32 lineno;
|
||||
Prog* link;
|
||||
short as;
|
||||
uchar scond; // arm only; condition codes
|
||||
|
||||
// operands
|
||||
uchar reg; // arm only
|
||||
uchar scond; // arm only
|
||||
Addr from;
|
||||
int16 reg; // arm, ppc64 only (e.g., ADD from, reg, to);
|
||||
// starts at 0 for both GPRs and FPRs;
|
||||
// also used for ADATA width on arm, ppc64
|
||||
Addr from3; // addl source argument (e.g., RLWM/FMADD from, reg, from3, to)
|
||||
Addr to;
|
||||
|
||||
// for 5g, 6g, 8g internal use
|
||||
void* opt;
|
||||
|
||||
// for liblink internal use
|
||||
// for 5l, 6l, 8l internal use
|
||||
Prog* forwd;
|
||||
Prog* pcond;
|
||||
Prog* comefrom; // amd64, 386
|
||||
Prog* pcrel; // arm
|
||||
Prog* comefrom; // 6l, 8l
|
||||
Prog* pcrel; // 5l
|
||||
int32 spadj;
|
||||
uint16 mark;
|
||||
uint16 optab; // arm, ppc64
|
||||
uchar back; // amd64, 386
|
||||
uchar ft; // oclass cache
|
||||
uchar tt; // oclass cache
|
||||
uchar isize; // amd64, 386
|
||||
uchar printed;
|
||||
uchar mark;
|
||||
uchar back; // 6l, 8l
|
||||
uchar ft; /* 6l, 8l oclass cache */
|
||||
uchar tt; // 6l, 8l
|
||||
uint16 optab; // 5l
|
||||
uchar isize; // 6l, 8l
|
||||
|
||||
char width; /* fake for DATA */
|
||||
char mode; /* 16, 32, or 64 in 6l, 8l; internal use in 5g, 6g, 8g */
|
||||
};
|
||||
|
||||
extern Prog zprog; // zeroed Prog
|
||||
|
||||
// Prog.as opcodes.
|
||||
// These are the portable opcodes, common to all architectures.
|
||||
// Each architecture defines many more arch-specific opcodes,
|
||||
// with values starting at A_ARCHSPECIFIC.
|
||||
enum {
|
||||
AXXX = 0,
|
||||
|
||||
ACALL,
|
||||
ACHECKNIL,
|
||||
ADATA,
|
||||
ADUFFCOPY,
|
||||
ADUFFZERO,
|
||||
AEND,
|
||||
AFUNCDATA,
|
||||
AGLOBL,
|
||||
AJMP,
|
||||
ANOP,
|
||||
APCDATA,
|
||||
ARET,
|
||||
ATEXT,
|
||||
ATYPE,
|
||||
AUNDEF,
|
||||
AUSEFIELD,
|
||||
AVARDEF,
|
||||
AVARKILL,
|
||||
|
||||
A_ARCHSPECIFIC, // first architecture-specific opcode value
|
||||
/*c2go uchar TEXTFLAG; */
|
||||
};
|
||||
|
||||
void nopout(Prog*);
|
||||
void nocache(Prog*);
|
||||
|
||||
// prevent incompatible type signatures between liblink and 8l on Plan 9
|
||||
#pragma incomplete struct Section
|
||||
|
||||
@@ -301,10 +136,8 @@ struct LSym
|
||||
uchar hide;
|
||||
uchar leaf; // arm only
|
||||
uchar fnptr; // arm only
|
||||
uchar localentry; // ppc64: instrs between global & local entry
|
||||
uchar seenglobl;
|
||||
uchar onlist; // on the textp or datap lists
|
||||
uchar printed;
|
||||
int16 symid; // for writing .5/.6/.8 files
|
||||
int32 dynid;
|
||||
int32 sig;
|
||||
@@ -372,7 +205,6 @@ enum
|
||||
SMACHO, /* Mach-O __nl_symbol_ptr */
|
||||
SMACHOGOT,
|
||||
SWINDOWS,
|
||||
SELFGOT, /* also .toc in ppc64 ABI */
|
||||
SNOPTRDATA,
|
||||
SINITARR,
|
||||
SDATA,
|
||||
@@ -401,12 +233,10 @@ enum
|
||||
enum
|
||||
{
|
||||
R_ADDR = 1,
|
||||
R_ADDRPOWER, // relocation for loading 31-bit address using addis and addi/ld/st for Power
|
||||
R_SIZE,
|
||||
R_CALL, // relocation for direct PC-relative call
|
||||
R_CALLARM, // relocation for ARM direct call
|
||||
R_CALLIND, // marker for indirect call (no actual relocating necessary)
|
||||
R_CALLPOWER, // relocation for Power direct call
|
||||
R_CONST,
|
||||
R_PCREL,
|
||||
R_TLS,
|
||||
@@ -417,23 +247,9 @@ enum
|
||||
R_PLT1,
|
||||
R_PLT2,
|
||||
R_USEFIELD,
|
||||
R_POWER_TOC, // ELF R_PPC64_TOC16*
|
||||
};
|
||||
|
||||
// Reloc.variant
|
||||
enum
|
||||
{
|
||||
RV_NONE, // identity variant
|
||||
RV_POWER_LO, // x & 0xFFFF
|
||||
RV_POWER_HI, // x >> 16
|
||||
RV_POWER_HA, // (x + 0x8000) >> 16
|
||||
RV_POWER_DS, // x & 0xFFFC, check x&0x3 == 0
|
||||
|
||||
RV_CHECK_OVERFLOW = 1<<8, // check overflow flag
|
||||
RV_TYPE_MASK = (RV_CHECK_OVERFLOW - 1),
|
||||
};
|
||||
|
||||
// Auto.name
|
||||
// Auto.type
|
||||
enum
|
||||
{
|
||||
A_AUTO = 1,
|
||||
@@ -445,7 +261,7 @@ struct Auto
|
||||
LSym* asym;
|
||||
Auto* link;
|
||||
int32 aoffset;
|
||||
int16 name;
|
||||
int16 type;
|
||||
LSym* gotype;
|
||||
};
|
||||
|
||||
@@ -460,7 +276,6 @@ struct Hist
|
||||
char* name;
|
||||
int32 line;
|
||||
int32 offset;
|
||||
uchar printed;
|
||||
};
|
||||
|
||||
struct Plist
|
||||
@@ -630,14 +445,47 @@ struct LinkArch
|
||||
int thechar; // '5', '6', and so on
|
||||
int32 endian; // LittleEndian or BigEndian
|
||||
|
||||
void (*preprocess)(Link*, LSym*);
|
||||
void (*addstacksplit)(Link*, LSym*);
|
||||
void (*assemble)(Link*, LSym*);
|
||||
int (*datasize)(Prog*);
|
||||
void (*follow)(Link*, LSym*);
|
||||
int (*iscall)(Prog*);
|
||||
int (*isdata)(Prog*);
|
||||
Prog* (*prg)(void);
|
||||
void (*progedit)(Link*, Prog*);
|
||||
void (*settextflag)(Prog*, int);
|
||||
int (*symtype)(Addr*);
|
||||
int (*textflag)(Prog*);
|
||||
|
||||
int minlc;
|
||||
int ptrsize;
|
||||
int regsize;
|
||||
|
||||
// TODO: Give these the same values on all systems.
|
||||
int D_ADDR;
|
||||
int D_AUTO;
|
||||
int D_BRANCH;
|
||||
int D_CONST;
|
||||
int D_EXTERN;
|
||||
int D_FCONST;
|
||||
int D_NONE;
|
||||
int D_PARAM;
|
||||
int D_SCONST;
|
||||
int D_STATIC;
|
||||
int D_OREG;
|
||||
|
||||
int ACALL;
|
||||
int ADATA;
|
||||
int AEND;
|
||||
int AFUNCDATA;
|
||||
int AGLOBL;
|
||||
int AJMP;
|
||||
int ANOP;
|
||||
int APCDATA;
|
||||
int ARET;
|
||||
int ATEXT;
|
||||
int ATYPE;
|
||||
int AUSEFIELD;
|
||||
};
|
||||
|
||||
/* executable header types */
|
||||
@@ -681,9 +529,6 @@ void span6(Link *ctxt, LSym *s);
|
||||
// asm8.c
|
||||
void span8(Link *ctxt, LSym *s);
|
||||
|
||||
// asm9.c
|
||||
void span9(Link *ctxt, LSym *s);
|
||||
|
||||
// data.c
|
||||
vlong addaddr(Link *ctxt, LSym *s, LSym *t);
|
||||
vlong addaddrplus(Link *ctxt, LSym *s, LSym *t, vlong add);
|
||||
@@ -714,11 +559,6 @@ void* emallocz(long n);
|
||||
void* erealloc(void *p, long n);
|
||||
char* estrdup(char *p);
|
||||
char* expandpkg(char *t0, char *pkg);
|
||||
void linksetexp(void);
|
||||
char* expstring(void);
|
||||
|
||||
extern int fieldtrack_enabled;
|
||||
extern int framepointer_enabled;
|
||||
|
||||
// ld.c
|
||||
void addhist(Link *ctxt, int32 line, int type);
|
||||
@@ -736,11 +576,10 @@ Prog* copyp(Link*, Prog*);
|
||||
Prog* appendp(Link*, Prog*);
|
||||
vlong atolwhex(char*);
|
||||
|
||||
// list[5689].c
|
||||
// list[568].c
|
||||
void listinit5(void);
|
||||
void listinit6(void);
|
||||
void listinit8(void);
|
||||
void listinit9(void);
|
||||
|
||||
// obj.c
|
||||
int linklinefmt(Link *ctxt, Fmt *fp);
|
||||
@@ -772,33 +611,20 @@ char* headstr(int);
|
||||
extern char* anames5[];
|
||||
extern char* anames6[];
|
||||
extern char* anames8[];
|
||||
extern char* anames9[];
|
||||
|
||||
extern char* cnames5[];
|
||||
extern char* cnames9[];
|
||||
|
||||
extern char* dnames5[];
|
||||
extern char* dnames6[];
|
||||
extern char* dnames8[];
|
||||
extern char* dnames9[];
|
||||
|
||||
extern LinkArch link386;
|
||||
extern LinkArch linkamd64;
|
||||
extern LinkArch linkamd64p32;
|
||||
extern LinkArch linkarm;
|
||||
extern LinkArch linkppc64;
|
||||
extern LinkArch linkppc64le;
|
||||
|
||||
extern int linkbasepointer;
|
||||
extern void linksetexp(void);
|
||||
|
||||
#pragma varargck type "A" int
|
||||
#pragma varargck type "E" uint
|
||||
#pragma varargck type "D" Addr*
|
||||
#pragma varargck type "lD" Addr*
|
||||
#pragma varargck type "P" Prog*
|
||||
#pragma varargck type "R" int
|
||||
#pragma varargck type "^" int // for 5l/9l, C_* classes (liblink internal)
|
||||
#pragma varargck type "^" int
|
||||
|
||||
// TODO(ality): remove this workaround.
|
||||
// It's here because Pconv in liblink/list?.c references %L.
|
||||
|
||||
@@ -14,10 +14,6 @@ char* getgoversion(void);
|
||||
char* getgoarm(void);
|
||||
char* getgo386(void);
|
||||
char* getgoextlinkenabled(void);
|
||||
char* getgohostos(void);
|
||||
char* getgohostarch(void);
|
||||
|
||||
int runcmd(char**);
|
||||
|
||||
void flagcount(char*, char*, int*);
|
||||
void flagint32(char*, char*, int32*);
|
||||
|
||||
@@ -42,7 +42,7 @@ extern "C" {
|
||||
#define _NETBSD_SOURCE 1 /* NetBSD */
|
||||
#define _DEFAULT_SOURCE 1 /* glibc > 2.19 */
|
||||
#define _SVID_SOURCE 1
|
||||
#if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__sun__)
|
||||
#if !defined(__APPLE__) && !defined(__OpenBSD__)
|
||||
# define _XOPEN_SOURCE 1000
|
||||
# define _XOPEN_SOURCE_EXTENDED 1
|
||||
#endif
|
||||
@@ -69,11 +69,8 @@ extern "C" {
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h> /* for tolower */
|
||||
#include <time.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
|
||||
/*
|
||||
* OS-specific crap
|
||||
|
||||
1
lib/codereview/codereview.cfg
Normal file
1
lib/codereview/codereview.cfg
Normal file
@@ -0,0 +1 @@
|
||||
defaultcc: golang-codereviews@googlegroups.com
|
||||
3692
lib/codereview/codereview.py
Normal file
3692
lib/codereview/codereview.py
Normal file
File diff suppressed because it is too large
Load Diff
199
lib/codereview/test.sh
Executable file
199
lib/codereview/test.sh
Executable file
@@ -0,0 +1,199 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2011 The Go Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
# Test the code review plugin.
|
||||
# Assumes a local Rietveld is running using the App Engine SDK
|
||||
# at http://localhost:7777/
|
||||
#
|
||||
# dev_appserver.py --port 7777 $HOME/pub/rietveld
|
||||
|
||||
codereview_script=$(pwd)/codereview.py
|
||||
server=localhost:7777
|
||||
master=/tmp/go.test
|
||||
clone1=/tmp/go.test1
|
||||
clone2=/tmp/go.test2
|
||||
export HGEDITOR=true
|
||||
|
||||
must() {
|
||||
if ! "$@"; then
|
||||
echo "$@" failed >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
not() {
|
||||
if "$@"; then
|
||||
false
|
||||
else
|
||||
true
|
||||
fi
|
||||
}
|
||||
|
||||
status() {
|
||||
echo '+++' "$@" >&2
|
||||
}
|
||||
|
||||
firstcl() {
|
||||
hg pending | sed 1q | tr -d ':'
|
||||
}
|
||||
|
||||
# Initial setup.
|
||||
status Create repositories.
|
||||
rm -rf $master $clone1 $clone2
|
||||
mkdir $master
|
||||
cd $master
|
||||
must hg init .
|
||||
echo Initial state >file
|
||||
must hg add file
|
||||
must hg ci -m 'first commit' file
|
||||
must hg clone $master $clone1
|
||||
must hg clone $master $clone2
|
||||
|
||||
echo "
|
||||
[ui]
|
||||
username=Grace R Emlin <gre@golang.org>
|
||||
[extensions]
|
||||
codereview=$codereview_script
|
||||
[codereview]
|
||||
testing=true
|
||||
server=$server
|
||||
" >>$clone1/.hg/hgrc
|
||||
cp $clone1/.hg/hgrc $clone2/.hg/hgrc
|
||||
|
||||
status Codereview should be disabled.
|
||||
cd $clone1
|
||||
must hg status
|
||||
must not hg pending
|
||||
|
||||
status Enabling code review.
|
||||
must mkdir lib lib/codereview
|
||||
must touch lib/codereview/codereview.cfg
|
||||
|
||||
status Code review should work even without CONTRIBUTORS.
|
||||
must hg pending
|
||||
|
||||
status Add CONTRIBUTORS.
|
||||
echo 'Grace R Emlin <gre@golang.org>' >CONTRIBUTORS
|
||||
must hg add lib/codereview/codereview.cfg CONTRIBUTORS
|
||||
|
||||
status First submit.
|
||||
must hg submit --tbr gre@golang.org -m codereview \
|
||||
lib/codereview/codereview.cfg CONTRIBUTORS
|
||||
|
||||
status Should see change in other client.
|
||||
cd $clone2
|
||||
must hg pull -u
|
||||
must test -f lib/codereview/codereview.cfg
|
||||
must test -f CONTRIBUTORS
|
||||
|
||||
test_clpatch() {
|
||||
# The email address must be test@example.com to match
|
||||
# the test code review server's default user.
|
||||
# Clpatch will check.
|
||||
|
||||
cd $clone1
|
||||
# dev_appserver.py used to crash with UTF-8 input.
|
||||
if true; then
|
||||
status Using UTF-8.
|
||||
name="Grácè T Emlïn <test@example.com>"
|
||||
else
|
||||
status Using ASCII.
|
||||
name="Grace T Emlin <test@example.com>"
|
||||
fi
|
||||
echo "$name" >>CONTRIBUTORS
|
||||
cat .hg/hgrc | sed "s/Grace.*/$name/" >/tmp/x && mv /tmp/x .hg/hgrc
|
||||
echo "
|
||||
Reviewer: gre@golang.org
|
||||
Description:
|
||||
CONTRIBUTORS: add $name
|
||||
Files:
|
||||
CONTRIBUTORS
|
||||
" | must hg change -i
|
||||
num=$(hg pending | sed 1q | tr -d :)
|
||||
|
||||
status Patch CL.
|
||||
cd $clone2
|
||||
must hg clpatch $num
|
||||
must [ "$num" = "$(firstcl)" ]
|
||||
must hg submit --tbr gre@golang.org $num
|
||||
|
||||
status Issue should be open with no reviewers.
|
||||
must curl http://$server/api/$num >/tmp/x
|
||||
must not grep '"closed":true' /tmp/x
|
||||
must grep '"reviewers":\[\]' /tmp/x
|
||||
|
||||
status Sync should close issue.
|
||||
cd $clone1
|
||||
must hg sync
|
||||
must curl http://$server/api/$num >/tmp/x
|
||||
must grep '"closed":true' /tmp/x
|
||||
must grep '"reviewers":\[\]' /tmp/x
|
||||
must [ "$(firstcl)" = "" ]
|
||||
}
|
||||
|
||||
test_reviewer() {
|
||||
status Submit without reviewer should fail.
|
||||
cd $clone1
|
||||
echo dummy >dummy
|
||||
must hg add dummy
|
||||
echo '
|
||||
Description:
|
||||
no reviewer
|
||||
Files:
|
||||
dummy
|
||||
' | must hg change -i
|
||||
num=$(firstcl)
|
||||
must not hg submit $num
|
||||
must hg revert dummy
|
||||
must rm dummy
|
||||
must hg change -d $num
|
||||
}
|
||||
|
||||
test_linearity() {
|
||||
status Linearity of changes.
|
||||
cd $clone1
|
||||
echo file1 >file1
|
||||
must hg add file1
|
||||
echo '
|
||||
Reviewer: gre@golang.org
|
||||
Description: file1
|
||||
Files: file1
|
||||
' | must hg change -i
|
||||
must hg submit --tbr gre@golang.org $(firstcl)
|
||||
|
||||
cd $clone2
|
||||
echo file2 >file2
|
||||
must hg add file2
|
||||
echo '
|
||||
Reviewer: gre@golang.org
|
||||
Description: file2
|
||||
Files: file2
|
||||
' | must hg change -i
|
||||
must not hg submit --tbr gre@golang.org $(firstcl)
|
||||
must hg sync
|
||||
must hg submit --tbr gre@golang.org $(firstcl)
|
||||
}
|
||||
|
||||
test_restrict() {
|
||||
status Cannot use hg ci.
|
||||
cd $clone1
|
||||
echo file1a >file1a
|
||||
hg add file1a
|
||||
must not hg ci -m commit file1a
|
||||
must rm file1a
|
||||
must hg revert file1a
|
||||
|
||||
status Cannot use hg rollback.
|
||||
must not hg rollback
|
||||
|
||||
status Cannot use hg backout
|
||||
must not hg backout -r -1
|
||||
}
|
||||
|
||||
test_reviewer
|
||||
test_clpatch
|
||||
test_linearity
|
||||
test_restrict
|
||||
status ALL TESTS PASSED.
|
||||
@@ -2,9 +2,9 @@ Android
|
||||
=======
|
||||
|
||||
For details on developing Go for Android, see the documentation in the
|
||||
mobile subrepository:
|
||||
go.mobile subrepository:
|
||||
|
||||
https://github.com/golang/mobile
|
||||
https://code.google.com/p/go/source/browse/README?repo=mobile
|
||||
|
||||
To run the standard library tests, see androidtest.bash. Run it as
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ package main
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
@@ -33,36 +32,33 @@ func run(args ...string) string {
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
const (
|
||||
// Directory structure on the target device androidtest.bash assumes.
|
||||
deviceGoroot = "/data/local/tmp/goroot"
|
||||
deviceGopath = "/data/local/tmp/gopath"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.SetFlags(0)
|
||||
log.SetPrefix("go_android_exec: ")
|
||||
|
||||
// Prepare a temporary directory that will be cleaned up at the end.
|
||||
deviceGotmp := fmt.Sprintf("/data/local/tmp/%s-%d",
|
||||
filepath.Base(os.Args[1]), os.Getpid())
|
||||
run("shell", "mkdir", "-p", deviceGotmp)
|
||||
|
||||
// Determine the package by examining the current working
|
||||
// Determine thepackage by examining the current working
|
||||
// directory, which will look something like
|
||||
// "$GOROOT/src/mime/multipart" or "$GOPATH/src/golang.org/x/mobile".
|
||||
// We extract everything after the $GOROOT or $GOPATH to run on the
|
||||
// same relative directory on the target device.
|
||||
subdir, inGoRoot := subdir()
|
||||
deviceCwd := filepath.Join(deviceGoroot, subdir)
|
||||
if !inGoRoot {
|
||||
deviceCwd = filepath.Join(deviceGopath, subdir)
|
||||
// "$GOROOT/src/mime/multipart". We extract everything
|
||||
// after the $GOROOT to run on the same relative directory
|
||||
// on the target device.
|
||||
//
|
||||
// TODO(crawshaw): Pick useful subdir when we are not
|
||||
// inside a GOROOT, e.g. we are in a GOPATH.
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
subdir, err := filepath.Rel(runtime.GOROOT(), cwd)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
subdir = filepath.ToSlash(subdir)
|
||||
|
||||
// Binary names can conflict.
|
||||
// E.g. template.test from the {html,text}/template packages.
|
||||
binName := filepath.Base(os.Args[1])
|
||||
deviceBin := fmt.Sprintf("%s/%s-%d", deviceGotmp, binName, os.Getpid())
|
||||
deviceGoroot := "/data/local/tmp/goroot"
|
||||
deviceBin := fmt.Sprintf("%s/%s-%d", deviceGoroot, binName, os.Getpid())
|
||||
|
||||
// The push of the binary happens in parallel with other tests.
|
||||
// Unfortunately, a simultaneous call to adb shell hold open
|
||||
@@ -75,22 +71,19 @@ func main() {
|
||||
|
||||
// The adb shell command will return an exit code of 0 regardless
|
||||
// of the command run. E.g.
|
||||
// $ adb shell false
|
||||
// $ echo $?
|
||||
// 0
|
||||
// $ adb shell false
|
||||
// $ echo $?
|
||||
// 0
|
||||
// https://code.google.com/p/android/issues/detail?id=3254
|
||||
// So we append the exitcode to the output and parse it from there.
|
||||
const exitstr = "exitcode="
|
||||
cmd := `export TMPDIR="` + deviceGotmp + `"` +
|
||||
cmd := `export TMPDIR="/data/local/tmp"` +
|
||||
`; export GOROOT="` + deviceGoroot + `"` +
|
||||
`; export GOPATH="` + deviceGopath + `"` +
|
||||
`; cd "` + deviceCwd + `"` +
|
||||
`; cd "$GOROOT/` + subdir + `"` +
|
||||
"; '" + deviceBin + "' " + strings.Join(os.Args[2:], " ") +
|
||||
"; echo -n " + exitstr + "$?"
|
||||
output := run("shell", cmd)
|
||||
|
||||
run("shell", "rm", "-rf", deviceGotmp) // Clean up.
|
||||
|
||||
run("shell", "rm '"+deviceBin+"'") // cleanup
|
||||
output = output[strings.LastIndex(output, "\n")+1:]
|
||||
if !strings.HasPrefix(output, exitstr) {
|
||||
log.Fatalf("no exit code: %q", output)
|
||||
@@ -101,32 +94,3 @@ func main() {
|
||||
}
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
// subdir determines the package based on the current working directory,
|
||||
// and returns the path to the package source relative to $GOROOT (or $GOPATH).
|
||||
func subdir() (pkgpath string, underGoRoot bool) {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if root := runtime.GOROOT(); strings.HasPrefix(cwd, root) {
|
||||
subdir, err := filepath.Rel(root, cwd)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return subdir, true
|
||||
}
|
||||
|
||||
for _, p := range filepath.SplitList(build.Default.GOPATH) {
|
||||
if !strings.HasPrefix(cwd, p) {
|
||||
continue
|
||||
}
|
||||
subdir, err := filepath.Rel(p, cwd)
|
||||
if err == nil {
|
||||
return subdir, false
|
||||
}
|
||||
}
|
||||
log.Fatalf("the current path %q is not in either GOROOT(%q) or GOPATH(%q)",
|
||||
cwd, runtime.GOROOT(), build.Default.GOPATH)
|
||||
return "", false
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package cgotest
|
||||
|
||||
import _ "unsafe"
|
||||
|
||||
//go:linkname lockedOSThread runtime.lockedOSThread
|
||||
//extern runtime_lockedOSThread
|
||||
func lockedOSThread() bool
|
||||
7
misc/cgo/test/backdoor/backdoor.go
Normal file
7
misc/cgo/test/backdoor/backdoor.go
Normal file
@@ -0,0 +1,7 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package backdoor
|
||||
|
||||
func LockedOSThread() bool // in thunk.s
|
||||
18
misc/cgo/test/backdoor/runtime_gccgo.c
Normal file
18
misc/cgo/test/backdoor/runtime_gccgo.c
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Expose some runtime functions for testing.
|
||||
// This is the gccgo version of runtime.c.
|
||||
|
||||
// +build gccgo
|
||||
|
||||
_Bool runtime_lockedOSThread(void);
|
||||
|
||||
_Bool LockedOSThread(void) asm(GOPKGPATH ".LockedOSThread");
|
||||
|
||||
_Bool
|
||||
LockedOSThread(void)
|
||||
{
|
||||
return runtime_lockedOSThread();
|
||||
}
|
||||
16
misc/cgo/test/backdoor/thunk.s
Normal file
16
misc/cgo/test/backdoor/thunk.s
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Assembly to get into package runtime without using exported symbols.
|
||||
|
||||
// +build amd64 amd64p32 arm 386
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
#ifdef GOARCH_arm
|
||||
#define JMP B
|
||||
#endif
|
||||
|
||||
TEXT ·LockedOSThread(SB),NOSPLIT,$0-0
|
||||
JMP runtime·lockedOSThread(SB)
|
||||
@@ -17,12 +17,13 @@ int returnAfterGrowFromGo(void);
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"unsafe"
|
||||
|
||||
"./backdoor"
|
||||
)
|
||||
|
||||
// nestedCall calls into C, back into Go, and finally to f.
|
||||
@@ -49,6 +50,8 @@ func testCallbackGC(t *testing.T) {
|
||||
nestedCall(runtime.GC)
|
||||
}
|
||||
|
||||
var lockedOSThread = backdoor.LockedOSThread
|
||||
|
||||
func testCallbackPanic(t *testing.T) {
|
||||
// Make sure panic during callback unwinds properly.
|
||||
if lockedOSThread() {
|
||||
@@ -168,9 +171,6 @@ func testCallbackCallers(t *testing.T) {
|
||||
"testing.tRunner",
|
||||
"runtime.goexit",
|
||||
}
|
||||
if unsafe.Sizeof((*byte)(nil)) == 8 {
|
||||
name[1] = "runtime.call32"
|
||||
}
|
||||
nestedCall(func() {
|
||||
n = runtime.Callers(2, pc)
|
||||
})
|
||||
@@ -212,19 +212,6 @@ func testPanicFromC(t *testing.T) {
|
||||
}
|
||||
|
||||
func testAllocateFromC(t *testing.T) {
|
||||
if strings.Contains(os.Getenv("GODEBUG"), "wbshadow=") {
|
||||
// This test is writing pointers to Go heap objects from C.
|
||||
// As such, those writes have no write barriers, and
|
||||
// wbshadow=2 mode correctly discovers that and crashes.
|
||||
// Disable test if any wbshadow mode is enabled.
|
||||
// TODO(rsc): I am not sure whether the test is fundamentally
|
||||
// incompatible with concurrent collection and should be
|
||||
// turned off or rewritten entirely. The test is attempting to
|
||||
// mimic some SWIG behavior, so it is important to work
|
||||
// through what we expect before trying SWIG and C++
|
||||
// with the concurrent collector.
|
||||
t.Skip("test is incompatible with wbshadow=")
|
||||
}
|
||||
C.callCgoAllocate() // crashes or exits on failure
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
// Test that the #cgo CFLAGS directive works,
|
||||
// with and without platform filters.
|
||||
// See http://golang.org/issue/5224 for details.
|
||||
// See http://code.google.com/p/go/issues/detail?id=5224 for details.
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
|
||||
@@ -9,4 +9,3 @@ import "testing"
|
||||
func TestSetgid(t *testing.T) { testSetgid(t) }
|
||||
func Test6997(t *testing.T) { test6997(t) }
|
||||
func TestBuildID(t *testing.T) { testBuildID(t) }
|
||||
func Test9400(t *testing.T) { test9400(t) }
|
||||
|
||||
@@ -63,6 +63,5 @@ func Test8811(t *testing.T) { test8811(t) }
|
||||
func TestReturnAfterGrow(t *testing.T) { testReturnAfterGrow(t) }
|
||||
func TestReturnAfterGrowFromGo(t *testing.T) { testReturnAfterGrowFromGo(t) }
|
||||
func Test9026(t *testing.T) { test9026(t) }
|
||||
func Test9557(t *testing.T) { test9557(t) }
|
||||
|
||||
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
|
||||
|
||||
@@ -14,7 +14,7 @@ import "testing"
|
||||
|
||||
var v7234 = [...]string{"runtime/cgo"}
|
||||
|
||||
func Test7234(t *testing.T) {
|
||||
func TestIssue7234(t *testing.T) {
|
||||
if v7234[0] != "runtime/cgo" {
|
||||
t.Errorf("bad string constant %q", v7234[0])
|
||||
}
|
||||
|
||||
@@ -12,23 +12,9 @@ package cgotest
|
||||
|
||||
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
|
||||
// Go code or OS dependencies
|
||||
static void issue7978c(uint32_t *sync) {
|
||||
#if HAS_SYNC_FETCH_AND_ADD
|
||||
while(__sync_fetch_and_add(sync, 0) != 0)
|
||||
;
|
||||
__sync_fetch_and_add(sync, 1);
|
||||
@@ -38,7 +24,6 @@ static void issue7978c(uint32_t *sync) {
|
||||
__sync_fetch_and_add(sync, 1);
|
||||
while(__sync_fetch_and_add(sync, 0) != 6)
|
||||
;
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
@@ -97,12 +82,6 @@ func issue7978go() {
|
||||
}
|
||||
|
||||
func test7978(t *testing.T) {
|
||||
if runtime.Compiler == "gccgo" {
|
||||
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")
|
||||
}
|
||||
if os.Getenv("GOTRACEBACK") != "2" {
|
||||
t.Fatalf("GOTRACEBACK must be 2")
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
#include "textflag.h"
|
||||
|
||||
TEXT ·RewindAndSetgid(SB),NOSPLIT,$0-0
|
||||
// Rewind stack pointer so anything that happens on the stack
|
||||
// will clobber the test pattern created by the caller
|
||||
ADDL $(1024 * 8), SP
|
||||
|
||||
// Ask signaller to setgid
|
||||
MOVL $1, ·Baton(SB)
|
||||
|
||||
// Wait for setgid completion
|
||||
loop:
|
||||
PAUSE
|
||||
MOVL ·Baton(SB), AX
|
||||
CMPL AX, $0
|
||||
JNE loop
|
||||
|
||||
// Restore stack
|
||||
SUBL $(1024 * 8), SP
|
||||
RET
|
||||
@@ -1,22 +0,0 @@
|
||||
// +build amd64 amd64p32
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
TEXT ·RewindAndSetgid(SB),NOSPLIT,$0-0
|
||||
// Rewind stack pointer so anything that happens on the stack
|
||||
// will clobber the test pattern created by the caller
|
||||
ADDQ $(1024 * 8), SP
|
||||
|
||||
// Ask signaller to setgid
|
||||
MOVL $1, ·Baton(SB)
|
||||
|
||||
// Wait for setgid completion
|
||||
loop:
|
||||
PAUSE
|
||||
MOVL ·Baton(SB), AX
|
||||
CMPL AX, $0
|
||||
JNE loop
|
||||
|
||||
// Restore stack
|
||||
SUBQ $(1024 * 8), SP
|
||||
RET
|
||||
@@ -1,33 +0,0 @@
|
||||
#include "textflag.h"
|
||||
|
||||
TEXT cas<>(SB),NOSPLIT,$0
|
||||
MOVW $0xffff0fc0, R15 // R15 is PC
|
||||
|
||||
TEXT ·RewindAndSetgid(SB),NOSPLIT,$-4-0
|
||||
// Save link register
|
||||
MOVW R14, R4
|
||||
|
||||
// Rewind stack pointer so anything that happens on the stack
|
||||
// will clobber the test pattern created by the caller
|
||||
ADD $(1024 * 8), R13
|
||||
|
||||
// Ask signaller to setgid
|
||||
MOVW $·Baton(SB), R2
|
||||
storeloop:
|
||||
MOVW 0(R2), R0
|
||||
MOVW $1, R1
|
||||
BL cas<>(SB)
|
||||
BCC storeloop
|
||||
|
||||
// Wait for setgid completion
|
||||
loop:
|
||||
MOVW $0, R0
|
||||
MOVW $0, R1
|
||||
BL cas<>(SB)
|
||||
BCC loop
|
||||
|
||||
// Restore stack
|
||||
SUB $(1024 * 8), R13
|
||||
|
||||
MOVW R4, R14
|
||||
RET
|
||||
@@ -1,27 +0,0 @@
|
||||
// +build ppc64 ppc64le
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
TEXT ·RewindAndSetgid(SB),NOSPLIT,$-8-0
|
||||
// Rewind stack pointer so anything that happens on the stack
|
||||
// will clobber the test pattern created by the caller
|
||||
ADD $(1024 * 8), R1
|
||||
|
||||
// Ask signaller to setgid
|
||||
MOVW $1, R3
|
||||
SYNC
|
||||
MOVW R3, ·Baton(SB)
|
||||
|
||||
// Wait for setgid completion
|
||||
loop:
|
||||
SYNC
|
||||
MOVW ·Baton(SB), R3
|
||||
CMP R3, $0
|
||||
// Hint that we're in a spin loop
|
||||
OR R1, R1, R1
|
||||
BNE loop
|
||||
ISYNC
|
||||
|
||||
// Restore stack
|
||||
SUB $(1024 * 8), R1
|
||||
RET
|
||||
@@ -1,9 +0,0 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package issue9400
|
||||
|
||||
var Baton int32
|
||||
|
||||
func RewindAndSetgid()
|
||||
@@ -1,58 +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.
|
||||
|
||||
// Test that SIGSETXID runs on signal stack, since it's likely to
|
||||
// overflow if it runs on the Go stack.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
|
||||
"./issue9400"
|
||||
)
|
||||
|
||||
func test9400(t *testing.T) {
|
||||
// We synchronize through a shared variable, so we need two procs
|
||||
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
|
||||
|
||||
// Start signaller
|
||||
atomic.StoreInt32(&issue9400.Baton, 0)
|
||||
go func() {
|
||||
// Wait for RewindAndSetgid
|
||||
for atomic.LoadInt32(&issue9400.Baton) == 0 {
|
||||
runtime.Gosched()
|
||||
}
|
||||
// Broadcast SIGSETXID
|
||||
runtime.LockOSThread()
|
||||
C.setgid(0)
|
||||
// Indicate that signalling is done
|
||||
atomic.StoreInt32(&issue9400.Baton, 0)
|
||||
}()
|
||||
|
||||
// Grow the stack and put down a test pattern
|
||||
const pattern = 0x123456789abcdef
|
||||
var big [1024]uint64 // len must match assmebly
|
||||
for i := range big {
|
||||
big[i] = pattern
|
||||
}
|
||||
|
||||
// Temporarily rewind the stack and trigger SIGSETXID
|
||||
issue9400.RewindAndSetgid()
|
||||
|
||||
// Check test pattern
|
||||
for i := range big {
|
||||
if big[i] != pattern {
|
||||
t.Fatalf("entry %d of test pattern is wrong; %#x != %#x", i, big[i], uint64(pattern))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// cgo rewrote C.var to *_Cvar_var, but left
|
||||
// C.var.field as _Cvar.var.field. It now rewrites
|
||||
// the latter as (*_Cvar_var).field.
|
||||
// See https://golang.org/issue/9557.
|
||||
|
||||
package cgotest
|
||||
|
||||
// struct issue9557_t {
|
||||
// int a;
|
||||
// } test9557bar = { 42 };
|
||||
//
|
||||
// struct issue9557_t *issue9557foo = &test9557bar;
|
||||
import "C"
|
||||
import "testing"
|
||||
|
||||
func test9557(t *testing.T) {
|
||||
// implicitly dereference a Go variable
|
||||
foo := C.issue9557foo
|
||||
if v := foo.a; v != 42 {
|
||||
t.Fatalf("foo.a expected 42, but got %d", v)
|
||||
}
|
||||
|
||||
// explicitly dereference a C variable
|
||||
if v := (*C.issue9557foo).a; v != 42 {
|
||||
t.Fatalf("(*C.issue9557foo).a expected 42, but is %d", v)
|
||||
}
|
||||
|
||||
// implicitly dereference a C variable
|
||||
if v := C.issue9557foo.a; v != 42 {
|
||||
t.Fatalf("C.issue9557foo.a expected 42, but is %d", v)
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Test that setgid does not hang on GNU/Linux.
|
||||
// See http://golang.org/issue/3871 for details.
|
||||
// See http://code.google.com/p/go/issues/detail?id=3871 for details.
|
||||
|
||||
package cgotest
|
||||
|
||||
|
||||
9
misc/cgo/testcdefs/cdefstest.c
Normal file
9
misc/cgo/testcdefs/cdefstest.c
Normal file
@@ -0,0 +1,9 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "runtime.h"
|
||||
#include "cdefstest.h"
|
||||
|
||||
struct CdefsTest test;
|
||||
struct PackedTest packed;
|
||||
60
misc/cgo/testcdefs/cdefstest.go
Normal file
60
misc/cgo/testcdefs/cdefstest.go
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
//
|
||||
// +build ignore
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
// This file tests a bug found in the cgo -cdefs tool that incorrectly
|
||||
// translated Go pointer arrays generated by the cgo godefs tool back into C
|
||||
// pointer arrays.
|
||||
//
|
||||
// The comments below show how the type is translated from gcc-style C into Go
|
||||
// and back into C for both the buggy version and the correct version
|
||||
|
||||
struct cdefsTest {
|
||||
// This was already being handled correctly
|
||||
// Correct: -> Array [20]int8 -> int8 array[20]
|
||||
char array1[20];
|
||||
|
||||
// Buggy: -> Array [20][20]int8 -> [20]int8 array[20]
|
||||
// Correct: -> Array [20][20]int8 -> int8 array[20][20]
|
||||
char array2[20][20];
|
||||
|
||||
// Buggy: -> Array [20]*int8 -> *int8 array[20]
|
||||
// Correct: -> Array [20]*int8 -> int8 *array[20]
|
||||
char *array3[20];
|
||||
|
||||
// Buggy: -> Array [20][20]*int8 -> [20]*int8 array[20]
|
||||
// Correct: -> Array [20]**int8 -> int8 *array[20][20]
|
||||
char *array4[20][20];
|
||||
|
||||
// Buggy: -> Array [20][20]**int8 -> [20]**int8 array[20]
|
||||
// Correct: -> Array [20][20]**int8 -> int8 **array[20][20]
|
||||
char **array5[20][20];
|
||||
};
|
||||
|
||||
// Test that packed structures can be translated to C correctly too.
|
||||
// See issue 8477.
|
||||
|
||||
struct packedTest {
|
||||
char first;
|
||||
int second;
|
||||
long long third;
|
||||
} __attribute__((packed));
|
||||
|
||||
// Test that conflicting type definitions don't cause problems with cgo.
|
||||
// See issue 8477.
|
||||
|
||||
typedef struct timespec {
|
||||
double bogus;
|
||||
} pid_t;
|
||||
|
||||
*/
|
||||
import "C"
|
||||
|
||||
type CdefsTest C.struct_cdefsTest
|
||||
|
||||
//type PackedTest C.struct_packedTest
|
||||
76
misc/cgo/testcdefs/main.c
Normal file
76
misc/cgo/testcdefs/main.c
Normal file
@@ -0,0 +1,76 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "runtime.h"
|
||||
#include "cdefstest.h"
|
||||
|
||||
void runtime·printf(int8*, ...);
|
||||
|
||||
// From cdefstest.go.
|
||||
typedef struct CdefsOrig CdefsOrig;
|
||||
struct CdefsOrig {
|
||||
int8 array1[20];
|
||||
int8 array2[20][20];
|
||||
int8 *array3[20];
|
||||
int8 *array4[20][20];
|
||||
int8 **array5[20][20];
|
||||
};
|
||||
|
||||
// Packed structs are no longer supported for -cdefs.
|
||||
/*
|
||||
typedef struct PackedOrig PackedOrig;
|
||||
#pragma pack on
|
||||
struct PackedOrig {
|
||||
int8 first;
|
||||
int32 second;
|
||||
int64 third;
|
||||
};
|
||||
#pragma pack off
|
||||
*/
|
||||
|
||||
void
|
||||
main·test(int32 ret)
|
||||
{
|
||||
CdefsOrig o;
|
||||
CdefsTest t;
|
||||
// PackedOrig po;
|
||||
// PackedTest pt;
|
||||
|
||||
ret = 0;
|
||||
if(sizeof(t.array1) != sizeof(o.array1) || offsetof(CdefsTest, array1[0]) != offsetof(CdefsOrig, array1[0])) {
|
||||
runtime·printf("array1: size, offset = %d, %d, want %d, %d\n", sizeof(t.array1), offsetof(CdefsTest, array1[0]), sizeof(o.array1), offsetof(CdefsOrig, array1[0]));
|
||||
ret = 1;
|
||||
}
|
||||
if(sizeof(t.array2) != sizeof(o.array2) || offsetof(CdefsTest, array2[0][0]) != offsetof(CdefsOrig, array2[0][0])) {
|
||||
runtime·printf("array2: size, offset = %d, %d, want %d, %d\n", sizeof(t.array2), offsetof(CdefsTest, array2[0][0]), sizeof(o.array2), offsetof(CdefsOrig, array2[0][0]));
|
||||
ret = 1;
|
||||
}
|
||||
if(sizeof(t.array3) != sizeof(o.array3) || offsetof(CdefsTest, array3[0]) != offsetof(CdefsOrig, array3[0])) {
|
||||
runtime·printf("array3: size, offset = %d, %d, want %d, %d\n", sizeof(t.array3), offsetof(CdefsTest, array3[0]), sizeof(o.array3), offsetof(CdefsOrig, array3[0]));
|
||||
ret = 1;
|
||||
}
|
||||
if(sizeof(t.array4) != sizeof(o.array4) || offsetof(CdefsTest, array4[0][0]) != offsetof(CdefsOrig, array4[0][0])) {
|
||||
runtime·printf("array4: size, offset = %d, %d, want %d, %d\n", sizeof(t.array4), offsetof(CdefsTest, array4[0][0]), sizeof(o.array4), offsetof(CdefsOrig, array4[0][0]));
|
||||
ret = 1;
|
||||
}
|
||||
if(sizeof(t.array5) != sizeof(o.array5) || offsetof(CdefsTest, array5[0][0]) != offsetof(CdefsOrig, array5[0][0])) {
|
||||
runtime·printf("array5: size, offset = %d, %d, want %d, %d\n", sizeof(t.array5), offsetof(CdefsTest, array5[0][0]), sizeof(o.array5), offsetof(CdefsOrig, array5[0][0]));
|
||||
ret = 1;
|
||||
}
|
||||
/*
|
||||
if(sizeof(pt.first) != sizeof(po.first) || offsetof(PackedTest, first) != offsetof(PackedOrig, first)) {
|
||||
runtime·printf("first: size, offset = %d, %d, want %d, %d\n", sizeof(pt.first), offsetof(PackedTest, first), sizeof(po.first), offsetof(PackedOrig, first));
|
||||
ret = 1;
|
||||
}
|
||||
if(sizeof(pt.second) != sizeof(po.second) || offsetof(PackedTest, second) != offsetof(PackedOrig, second)) {
|
||||
runtime·printf("second: size, offset = %d, %d, want %d, %d\n", sizeof(pt.second), offsetof(PackedTest, second), sizeof(po.second), offsetof(PackedOrig, second));
|
||||
ret = 1;
|
||||
}
|
||||
if(sizeof(pt.third) != sizeof(po.third) || offsetof(PackedTest, third) != offsetof(PackedOrig, third)) {
|
||||
runtime·printf("third: size, offset = %d, %d, want %d, %d\n", sizeof(pt.third), offsetof(PackedTest, third), sizeof(po.third), offsetof(PackedOrig, third));
|
||||
ret = 1;
|
||||
}
|
||||
*/
|
||||
FLUSH(&ret); // flush return value
|
||||
}
|
||||
@@ -2,8 +2,12 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gc
|
||||
package main
|
||||
|
||||
const (
|
||||
DEFAULTCAPACITY = 16
|
||||
)
|
||||
import "os"
|
||||
|
||||
func test() int32 // in main.c
|
||||
|
||||
func main() {
|
||||
os.Exit(int(test()))
|
||||
}
|
||||
16
misc/cgo/testcdefs/test.bash
Executable file
16
misc/cgo/testcdefs/test.bash
Executable file
@@ -0,0 +1,16 @@
|
||||
# Copyright 2013 The Go Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
# Just add issue file prefixes to this list if more issues come up
|
||||
FILE_PREFIXES="cdefstest"
|
||||
|
||||
for FP in $FILE_PREFIXES
|
||||
do
|
||||
go tool cgo -cdefs ${FP}.go > ${FP}.h
|
||||
done
|
||||
|
||||
go build . && ./testcdefs
|
||||
EXIT=$?
|
||||
rm -rf _obj testcdefs *.h
|
||||
exit $EXIT
|
||||
@@ -5,12 +5,6 @@
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$(uname -m)" == ppc64 -o "$(uname -m)" == ppc64le ]; then
|
||||
# External linking not implemented on ppc64
|
||||
echo "skipping test on ppc64 (issue #8912)"
|
||||
exit
|
||||
fi
|
||||
|
||||
args=
|
||||
dyld_envvar=LD_LIBRARY_PATH
|
||||
ext=so
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
var numericRE = /^\d+$/;
|
||||
var commitRE = /^(?:\d+:)?([0-9a-f]{6,40})$/; // e.g "8486:ab29d2698a47" or "ab29d2698a47"
|
||||
var gerritChangeIdRE = /^I[0-9a-f]{4,40}$/; // e.g. Id69c00d908d18151486007ec03da5495b34b05f5
|
||||
var commitRE = /^(?:\d+:)?([0-9a-f]{6,20})$/; // e.g "8486:ab29d2698a47" or "ab29d2698a47"
|
||||
var pkgRE = /^[a-z0-9_\/]+$/;
|
||||
|
||||
function urlForInput(t) {
|
||||
@@ -14,26 +13,20 @@ function urlForInput(t) {
|
||||
|
||||
if (numericRE.test(t)) {
|
||||
if (t < 150000) {
|
||||
// We could use the golang.org/cl/ handler here, but
|
||||
// avoid some redirect latency and go right there, since
|
||||
// one is easy. (no server-side mapping)
|
||||
return "https://github.com/golang/go/issues/" + t;
|
||||
return "http://code.google.com/p/go/issues/detail?id=" + t;
|
||||
}
|
||||
return "https://golang.org/cl/" + t;
|
||||
}
|
||||
|
||||
if (gerritChangeIdRE.test(t)) {
|
||||
return "http://golang.org/cl/" + t;
|
||||
return "http://codereview.appspot.com/" + t + "/";
|
||||
}
|
||||
|
||||
var match = commitRE.exec(t);
|
||||
if (match) {
|
||||
return "https://golang.org/change/" + match[1];
|
||||
return "http://code.google.com/p/go/source/detail?r=" + match[1];
|
||||
}
|
||||
|
||||
if (pkgRE.test(t)) {
|
||||
// TODO: make this smarter, using a list of packages + substring matches.
|
||||
// Get the list from godoc itself in JSON format?
|
||||
// TODO: prefer localhost:6060 to golang.org if localhost:6060 is responding.
|
||||
return "http://golang.org/pkg/" + t;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,13 +9,11 @@
|
||||
<script src="popup.js"></script>
|
||||
</head>
|
||||
<body style='margin: 0.5em; font-family: sans;'>
|
||||
<small><a href="#" url="https://golang.org/issue">issue</a>,
|
||||
<a href="#" url="https://golang.org/cl">codereview</a>,
|
||||
<a href="#" url="https://golang.org/change">commit</a>, or
|
||||
<a href="#" url="https://golang.org/pkg/">pkg</a> id/name:</small>
|
||||
<small><a href="#" url="http://code.google.com/p/go/issues/list">issue</a>,
|
||||
<a href="#" url="http://codereview.appspot.com/">codereview</a>,
|
||||
<a href="#" url="http://code.google.com/p/go/source/list">commit</a>, or
|
||||
<a href="#" url="http://golang.org/pkg/">pkg</a> id/name:</small>
|
||||
<form style='margin: 0' id='navform'><nobr><input id="inputbox" size=10 tabindex=1 /><input type="submit" value="go" /></nobr></form>
|
||||
<small>Also: <a href="#" url="https://build.golang.org">buildbots</a>
|
||||
<a href="#" url="https://github.com/golang/go">Github</a>
|
||||
</small>
|
||||
<small>Also: <a href="#" url="http://build.golang.org">buildbots</a></small>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
24
misc/dashboard/codereview/app.yaml
Normal file
24
misc/dashboard/codereview/app.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
application: gocodereview
|
||||
version: 1
|
||||
runtime: go
|
||||
api_version: go1
|
||||
|
||||
inbound_services:
|
||||
- mail
|
||||
|
||||
handlers:
|
||||
- url: /static/(.*)
|
||||
static_files: static/\1
|
||||
upload: static/.*
|
||||
- url: /_ah/mail/.*
|
||||
script: _go_app
|
||||
login: admin
|
||||
- url: /_ah/queue/go/delay
|
||||
script: _go_app
|
||||
login: admin
|
||||
- url: /(gc|update-cl)
|
||||
script: _go_app
|
||||
login: admin
|
||||
- url: /.*
|
||||
script: _go_app
|
||||
login: required
|
||||
4
misc/dashboard/codereview/cron.yaml
Normal file
4
misc/dashboard/codereview/cron.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
cron:
|
||||
- description: GC
|
||||
url: /gc
|
||||
schedule: every 6 hours
|
||||
493
misc/dashboard/codereview/dashboard/cl.go
Normal file
493
misc/dashboard/codereview/dashboard/cl.go
Normal file
@@ -0,0 +1,493 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package dashboard
|
||||
|
||||
// This file handles operations on the CL entity kind.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"appengine"
|
||||
"appengine/datastore"
|
||||
"appengine/taskqueue"
|
||||
"appengine/urlfetch"
|
||||
"appengine/user"
|
||||
)
|
||||
|
||||
func init() {
|
||||
http.HandleFunc("/assign", handleAssign)
|
||||
http.HandleFunc("/update-cl", handleUpdateCL)
|
||||
}
|
||||
|
||||
const codereviewBase = "http://codereview.appspot.com"
|
||||
const gobotBase = "http://research.swtch.com/gobot_codereview"
|
||||
|
||||
var clRegexp = regexp.MustCompile(`\d+`)
|
||||
|
||||
// CL represents a code review.
|
||||
type CL struct {
|
||||
Number string // e.g. "5903061"
|
||||
Closed bool
|
||||
Owner string // email address
|
||||
|
||||
Created, Modified time.Time
|
||||
|
||||
Description []byte `datastore:",noindex"`
|
||||
FirstLine string `datastore:",noindex"`
|
||||
LGTMs []string
|
||||
NotLGTMs []string
|
||||
LastUpdateBy string // author of most recent review message
|
||||
LastUpdate string `datastore:",noindex"` // first line of most recent review message
|
||||
|
||||
// Mail information.
|
||||
Subject string `datastore:",noindex"`
|
||||
Recipients []string `datastore:",noindex"`
|
||||
LastMessageID string `datastore:",noindex"`
|
||||
|
||||
// These are person IDs (e.g. "rsc"); they may be empty
|
||||
Author string
|
||||
Reviewer string
|
||||
}
|
||||
|
||||
// Reviewed reports whether the reviewer has replied to the CL.
|
||||
// The heuristic is that the CL has been replied to if it is LGTMed
|
||||
// or if the last CL message was from the reviewer.
|
||||
func (cl *CL) Reviewed() bool {
|
||||
if cl.LastUpdateBy == cl.Reviewer {
|
||||
return true
|
||||
}
|
||||
if person := emailToPerson[cl.LastUpdateBy]; person != "" && person == cl.Reviewer {
|
||||
return true
|
||||
}
|
||||
for _, who := range cl.LGTMs {
|
||||
if who == cl.Reviewer {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// DisplayOwner returns the CL's owner, either as their email address
|
||||
// or the person ID if it's a reviewer. It is for display only.
|
||||
func (cl *CL) DisplayOwner() string {
|
||||
if p, ok := emailToPerson[cl.Owner]; ok {
|
||||
return p
|
||||
}
|
||||
return cl.Owner
|
||||
}
|
||||
|
||||
func (cl *CL) FirstLineHTML() template.HTML {
|
||||
s := template.HTMLEscapeString(cl.FirstLine)
|
||||
// Embolden the package name.
|
||||
if i := strings.Index(s, ":"); i >= 0 {
|
||||
s = "<b>" + s[:i] + "</b>" + s[i:]
|
||||
}
|
||||
return template.HTML(s)
|
||||
}
|
||||
|
||||
func formatEmails(e []string) template.HTML {
|
||||
x := make([]string, len(e))
|
||||
for i, s := range e {
|
||||
s = template.HTMLEscapeString(s)
|
||||
if !strings.Contains(s, "@") {
|
||||
s = "<b>" + s + "</b>"
|
||||
}
|
||||
s = `<span class="email">` + s + "</span>"
|
||||
x[i] = s
|
||||
}
|
||||
return template.HTML(strings.Join(x, ", "))
|
||||
}
|
||||
|
||||
func (cl *CL) LGTMHTML() template.HTML {
|
||||
return formatEmails(cl.LGTMs)
|
||||
}
|
||||
|
||||
func (cl *CL) NotLGTMHTML() template.HTML {
|
||||
return formatEmails(cl.NotLGTMs)
|
||||
}
|
||||
|
||||
func (cl *CL) ModifiedAgo() string {
|
||||
// Just the first non-zero unit.
|
||||
units := [...]struct {
|
||||
suffix string
|
||||
unit time.Duration
|
||||
}{
|
||||
{"d", 24 * time.Hour},
|
||||
{"h", time.Hour},
|
||||
{"m", time.Minute},
|
||||
{"s", time.Second},
|
||||
}
|
||||
d := time.Now().Sub(cl.Modified)
|
||||
for _, u := range units {
|
||||
if d > u.unit {
|
||||
return fmt.Sprintf("%d%s", d/u.unit, u.suffix)
|
||||
}
|
||||
}
|
||||
return "just now"
|
||||
}
|
||||
|
||||
func handleAssign(w http.ResponseWriter, r *http.Request) {
|
||||
c := appengine.NewContext(r)
|
||||
|
||||
if r.Method != "POST" {
|
||||
http.Error(w, "Bad method "+r.Method, 400)
|
||||
return
|
||||
}
|
||||
|
||||
u := user.Current(c)
|
||||
person, ok := emailToPerson[u.Email]
|
||||
if !ok {
|
||||
http.Error(w, "Not allowed", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
n, rev := r.FormValue("cl"), r.FormValue("r")
|
||||
if !clRegexp.MatchString(n) {
|
||||
c.Errorf("Bad CL %q", n)
|
||||
http.Error(w, "Bad CL", 400)
|
||||
return
|
||||
}
|
||||
if _, ok := preferredEmail[rev]; !ok && rev != "" {
|
||||
c.Errorf("Unknown reviewer %q", rev)
|
||||
http.Error(w, "Unknown reviewer", 400)
|
||||
return
|
||||
}
|
||||
|
||||
key := datastore.NewKey(c, "CL", n, 0, nil)
|
||||
|
||||
if rev != "" {
|
||||
// Make sure the reviewer is listed in Rietveld as a reviewer.
|
||||
url := codereviewBase + "/" + n + "/fields"
|
||||
resp, err := urlfetch.Client(c).Get(url + "?field=reviewers")
|
||||
if err != nil {
|
||||
c.Errorf("Retrieving CL reviewer list failed: %v", err)
|
||||
http.Error(w, err.Error(), 500)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
c.Errorf("Failed reading body: %v", err)
|
||||
http.Error(w, err.Error(), 500)
|
||||
return
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
c.Errorf("Retrieving CL reviewer list failed: got HTTP response %d\nBody: %s", resp.StatusCode, body)
|
||||
http.Error(w, "Failed contacting Rietveld", 500)
|
||||
return
|
||||
}
|
||||
|
||||
var apiResp struct {
|
||||
Reviewers []string `json:"reviewers"`
|
||||
}
|
||||
if err := json.Unmarshal(body, &apiResp); err != nil {
|
||||
// probably can't be retried
|
||||
msg := fmt.Sprintf("Malformed JSON from %v: %v", url, err)
|
||||
c.Errorf("%s", msg)
|
||||
http.Error(w, msg, 500)
|
||||
return
|
||||
}
|
||||
found := false
|
||||
for _, r := range apiResp.Reviewers {
|
||||
if emailToPerson[r] == rev {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
c.Infof("Adding %v as a reviewer of CL %v", rev, n)
|
||||
|
||||
url := fmt.Sprintf("%s?cl=%s&r=%s&obo=%s", gobotBase, n, rev, person)
|
||||
resp, err := urlfetch.Client(c).Get(url)
|
||||
if err != nil {
|
||||
c.Errorf("Gobot GET failed: %v", err)
|
||||
http.Error(w, err.Error(), 500)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
c.Errorf("Failed reading Gobot body: %v", err)
|
||||
http.Error(w, err.Error(), 500)
|
||||
return
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
c.Errorf("Gobot GET failed: got HTTP response %d\nBody: %s", resp.StatusCode, body)
|
||||
http.Error(w, "Failed contacting Gobot", 500)
|
||||
return
|
||||
}
|
||||
|
||||
c.Infof("Gobot said %q", resp.Status)
|
||||
}
|
||||
}
|
||||
|
||||
// Update our own record.
|
||||
err := datastore.RunInTransaction(c, func(c appengine.Context) error {
|
||||
cl := new(CL)
|
||||
err := datastore.Get(c, key, cl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cl.Reviewer = rev
|
||||
_, err = datastore.Put(c, key, cl)
|
||||
return err
|
||||
}, nil)
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("Assignment failed: %v", err)
|
||||
c.Errorf("%s", msg)
|
||||
http.Error(w, msg, 500)
|
||||
return
|
||||
}
|
||||
c.Infof("Assigned CL %v to %v", n, rev)
|
||||
}
|
||||
|
||||
func UpdateCLLater(c appengine.Context, n string, delay time.Duration) {
|
||||
t := taskqueue.NewPOSTTask("/update-cl", url.Values{
|
||||
"cl": []string{n},
|
||||
})
|
||||
t.Delay = delay
|
||||
if _, err := taskqueue.Add(c, t, "update-cl"); err != nil {
|
||||
c.Errorf("Failed adding task: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func handleUpdateCL(w http.ResponseWriter, r *http.Request) {
|
||||
c := appengine.NewContext(r)
|
||||
|
||||
n := r.FormValue("cl")
|
||||
if !clRegexp.MatchString(n) {
|
||||
c.Errorf("Bad CL %q", n)
|
||||
http.Error(w, "Bad CL", 400)
|
||||
return
|
||||
}
|
||||
|
||||
if err := updateCL(c, n); err != nil {
|
||||
c.Errorf("Failed updating CL %v: %v", n, err)
|
||||
http.Error(w, "Failed update", 500)
|
||||
return
|
||||
}
|
||||
|
||||
io.WriteString(w, "OK")
|
||||
}
|
||||
|
||||
// apiMessage describes the JSON sent back by Rietveld in the CL messages list.
|
||||
type apiMessage struct {
|
||||
Date string `json:"date"`
|
||||
Text string `json:"text"`
|
||||
Sender string `json:"sender"`
|
||||
Recipients []string `json:"recipients"`
|
||||
Approval bool `json:"approval"`
|
||||
}
|
||||
|
||||
// byDate implements sort.Interface to order the messages by date, earliest first.
|
||||
// The dates are sent in RFC 3339 format, so string comparison matches time value comparison.
|
||||
type byDate []*apiMessage
|
||||
|
||||
func (x byDate) Len() int { return len(x) }
|
||||
func (x byDate) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||
func (x byDate) Less(i, j int) bool { return x[i].Date < x[j].Date }
|
||||
|
||||
// updateCL updates a single CL. If a retryable failure occurs, an error is returned.
|
||||
func updateCL(c appengine.Context, n string) error {
|
||||
c.Debugf("Updating CL %v", n)
|
||||
key := datastore.NewKey(c, "CL", n, 0, nil)
|
||||
|
||||
url := codereviewBase + "/api/" + n + "?messages=true"
|
||||
resp, err := urlfetch.Client(c).Get(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
raw, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed reading HTTP body: %v", err)
|
||||
}
|
||||
|
||||
// Special case for abandoned CLs.
|
||||
if resp.StatusCode == 404 && bytes.Contains(raw, []byte("No issue exists with that id")) {
|
||||
// Don't bother checking for errors. The CL might never have been saved, for instance.
|
||||
datastore.Delete(c, key)
|
||||
c.Infof("Deleted abandoned CL %v", n)
|
||||
return nil
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return fmt.Errorf("Update: got HTTP response %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
var apiResp struct {
|
||||
Description string `json:"description"`
|
||||
Reviewers []string `json:"reviewers"`
|
||||
Created string `json:"created"`
|
||||
OwnerEmail string `json:"owner_email"`
|
||||
Modified string `json:"modified"`
|
||||
Closed bool `json:"closed"`
|
||||
Subject string `json:"subject"`
|
||||
Messages []*apiMessage `json:"messages"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &apiResp); err != nil {
|
||||
// probably can't be retried
|
||||
c.Errorf("Malformed JSON from %v: %v", url, err)
|
||||
return nil
|
||||
}
|
||||
//c.Infof("RAW: %+v", apiResp)
|
||||
sort.Sort(byDate(apiResp.Messages))
|
||||
|
||||
cl := &CL{
|
||||
Number: n,
|
||||
Closed: apiResp.Closed,
|
||||
Owner: apiResp.OwnerEmail,
|
||||
Description: []byte(apiResp.Description),
|
||||
FirstLine: apiResp.Description,
|
||||
Subject: apiResp.Subject,
|
||||
Author: emailToPerson[apiResp.OwnerEmail],
|
||||
}
|
||||
cl.Created, err = time.Parse("2006-01-02 15:04:05.000000", apiResp.Created)
|
||||
if err != nil {
|
||||
c.Errorf("Bad creation time %q: %v", apiResp.Created, err)
|
||||
}
|
||||
cl.Modified, err = time.Parse("2006-01-02 15:04:05.000000", apiResp.Modified)
|
||||
if err != nil {
|
||||
c.Errorf("Bad modification time %q: %v", apiResp.Modified, err)
|
||||
}
|
||||
if i := strings.Index(cl.FirstLine, "\n"); i >= 0 {
|
||||
cl.FirstLine = cl.FirstLine[:i]
|
||||
}
|
||||
// Treat zero reviewers as a signal that the CL is completed.
|
||||
// This could be after the CL has been submitted, but before the CL author has synced,
|
||||
// but it could also be a CL manually edited to remove reviewers.
|
||||
if len(apiResp.Reviewers) == 0 {
|
||||
cl.Closed = true
|
||||
}
|
||||
|
||||
lgtm := make(map[string]bool)
|
||||
notLGTM := make(map[string]bool)
|
||||
rcpt := make(map[string]bool)
|
||||
for _, msg := range apiResp.Messages {
|
||||
s, rev := msg.Sender, false
|
||||
if p, ok := emailToPerson[s]; ok {
|
||||
s, rev = p, true
|
||||
}
|
||||
|
||||
line := firstLine(msg.Text)
|
||||
if line != "" {
|
||||
cl.LastUpdateBy = msg.Sender
|
||||
cl.LastUpdate = line
|
||||
}
|
||||
|
||||
// CLs submitted by someone other than the CL owner do not immediately
|
||||
// transition to "closed". Let's simulate the intention by treating
|
||||
// messages starting with "*** Submitted as " from a reviewer as a
|
||||
// signal that the CL is now closed.
|
||||
if rev && strings.HasPrefix(msg.Text, "*** Submitted as ") {
|
||||
cl.Closed = true
|
||||
}
|
||||
|
||||
if msg.Approval {
|
||||
lgtm[s] = true
|
||||
delete(notLGTM, s) // "LGTM" overrules previous "NOT LGTM"
|
||||
}
|
||||
if strings.Contains(line, "NOT LGTM") {
|
||||
notLGTM[s] = true
|
||||
delete(lgtm, s) // "NOT LGTM" overrules previous "LGTM"
|
||||
}
|
||||
|
||||
for _, r := range msg.Recipients {
|
||||
rcpt[r] = true
|
||||
}
|
||||
}
|
||||
for l := range lgtm {
|
||||
cl.LGTMs = append(cl.LGTMs, l)
|
||||
}
|
||||
for l := range notLGTM {
|
||||
cl.NotLGTMs = append(cl.NotLGTMs, l)
|
||||
}
|
||||
for r := range rcpt {
|
||||
cl.Recipients = append(cl.Recipients, r)
|
||||
}
|
||||
sort.Strings(cl.LGTMs)
|
||||
sort.Strings(cl.NotLGTMs)
|
||||
sort.Strings(cl.Recipients)
|
||||
|
||||
err = datastore.RunInTransaction(c, func(c appengine.Context) error {
|
||||
ocl := new(CL)
|
||||
err := datastore.Get(c, key, ocl)
|
||||
if err != nil && err != datastore.ErrNoSuchEntity {
|
||||
return err
|
||||
} else if err == nil {
|
||||
// LastMessageID and Reviewer need preserving.
|
||||
cl.LastMessageID = ocl.LastMessageID
|
||||
cl.Reviewer = ocl.Reviewer
|
||||
}
|
||||
_, err = datastore.Put(c, key, cl)
|
||||
return err
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Infof("Updated CL %v", n)
|
||||
return nil
|
||||
}
|
||||
|
||||
// trailingSpaceRE matches trailing spaces.
|
||||
var trailingSpaceRE = regexp.MustCompile(`(?m)[ \t\r]+$`)
|
||||
|
||||
// removeRE is the list of patterns to skip over at the beginning of a
|
||||
// message when looking for message text.
|
||||
var removeRE = regexp.MustCompile(`(?m-s)\A(` +
|
||||
// Skip leading "Hello so-and-so," generated by codereview plugin.
|
||||
`(Hello(.|\n)*?\n\n)` +
|
||||
|
||||
// Skip quoted text.
|
||||
`|((On.*|.* writes|.* wrote):\n)` +
|
||||
`|((>.*\n)+)` +
|
||||
|
||||
// Skip lines with no letters.
|
||||
`|(([^A-Za-z]*\n)+)` +
|
||||
|
||||
// Skip links to comments and file info.
|
||||
`|(http://codereview.*\n([^ ]+:[0-9]+:.*\n)?)` +
|
||||
`|(File .*:\n)` +
|
||||
|
||||
`)`,
|
||||
)
|
||||
|
||||
// firstLine returns the first interesting line of the message text.
|
||||
func firstLine(text string) string {
|
||||
// Cut trailing spaces.
|
||||
text = trailingSpaceRE.ReplaceAllString(text, "")
|
||||
|
||||
// Skip uninteresting lines.
|
||||
for {
|
||||
text = strings.TrimSpace(text)
|
||||
m := removeRE.FindStringIndex(text)
|
||||
if m == nil || m[0] != 0 {
|
||||
break
|
||||
}
|
||||
text = text[m[1]:]
|
||||
}
|
||||
|
||||
// Chop line at newline or else at 74 bytes.
|
||||
i := strings.Index(text, "\n")
|
||||
if i >= 0 {
|
||||
text = text[:i]
|
||||
}
|
||||
if len(text) > 74 {
|
||||
text = text[:70] + "..."
|
||||
}
|
||||
return text
|
||||
}
|
||||
299
misc/dashboard/codereview/dashboard/front.go
Normal file
299
misc/dashboard/codereview/dashboard/front.go
Normal file
@@ -0,0 +1,299 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package dashboard
|
||||
|
||||
// This file handles the front page.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"html/template"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"appengine"
|
||||
"appengine/datastore"
|
||||
"appengine/user"
|
||||
)
|
||||
|
||||
func init() {
|
||||
http.HandleFunc("/", handleFront)
|
||||
http.HandleFunc("/favicon.ico", http.NotFound)
|
||||
}
|
||||
|
||||
// maximum number of active CLs to show in person-specific tables.
|
||||
const maxCLs = 100
|
||||
|
||||
func handleFront(w http.ResponseWriter, r *http.Request) {
|
||||
c := appengine.NewContext(r)
|
||||
|
||||
data := &frontPageData{
|
||||
Reviewers: personList,
|
||||
User: user.Current(c).Email,
|
||||
IsAdmin: user.IsAdmin(c),
|
||||
}
|
||||
var currentPerson string
|
||||
u := data.User
|
||||
you := "you"
|
||||
if e := r.FormValue("user"); e != "" {
|
||||
u = e
|
||||
you = e
|
||||
}
|
||||
currentPerson, data.UserIsReviewer = emailToPerson[u]
|
||||
if !data.UserIsReviewer {
|
||||
currentPerson = u
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
errc := make(chan error, 10)
|
||||
activeCLs := datastore.NewQuery("CL").
|
||||
Filter("Closed =", false).
|
||||
Order("-Modified")
|
||||
|
||||
tableFetch := func(index int, f func(tbl *clTable) error) {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
start := time.Now()
|
||||
if err := f(&data.Tables[index]); err != nil {
|
||||
errc <- err
|
||||
}
|
||||
data.Timing[index] = time.Now().Sub(start)
|
||||
}()
|
||||
}
|
||||
|
||||
data.Tables[0].Title = "CLs assigned to " + you + " for review"
|
||||
if data.UserIsReviewer {
|
||||
tableFetch(0, func(tbl *clTable) error {
|
||||
q := activeCLs.Filter("Reviewer =", currentPerson).Limit(maxCLs)
|
||||
tbl.Assignable = true
|
||||
_, err := q.GetAll(c, &tbl.CLs)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
tableFetch(1, func(tbl *clTable) error {
|
||||
q := activeCLs
|
||||
if data.UserIsReviewer {
|
||||
q = q.Filter("Author =", currentPerson)
|
||||
} else {
|
||||
q = q.Filter("Owner =", currentPerson)
|
||||
}
|
||||
q = q.Limit(maxCLs)
|
||||
tbl.Title = "CLs sent by " + you
|
||||
tbl.Assignable = true
|
||||
_, err := q.GetAll(c, &tbl.CLs)
|
||||
return err
|
||||
})
|
||||
|
||||
tableFetch(2, func(tbl *clTable) error {
|
||||
q := activeCLs.Limit(50)
|
||||
tbl.Title = "Other active CLs"
|
||||
tbl.Assignable = true
|
||||
if _, err := q.GetAll(c, &tbl.CLs); err != nil {
|
||||
return err
|
||||
}
|
||||
// filter
|
||||
for i := len(tbl.CLs) - 1; i >= 0; i-- {
|
||||
cl := tbl.CLs[i]
|
||||
if cl.Owner == currentPerson || cl.Author == currentPerson || cl.Reviewer == currentPerson {
|
||||
// Preserve order.
|
||||
copy(tbl.CLs[i:], tbl.CLs[i+1:])
|
||||
tbl.CLs = tbl.CLs[:len(tbl.CLs)-1]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
tableFetch(3, func(tbl *clTable) error {
|
||||
q := datastore.NewQuery("CL").
|
||||
Filter("Closed =", true).
|
||||
Order("-Modified").
|
||||
Limit(10)
|
||||
tbl.Title = "Recently closed CLs"
|
||||
tbl.Assignable = false
|
||||
_, err := q.GetAll(c, &tbl.CLs)
|
||||
return err
|
||||
})
|
||||
|
||||
// Not really a table fetch.
|
||||
tableFetch(0, func(_ *clTable) error {
|
||||
var err error
|
||||
data.LogoutURL, err = user.LogoutURL(c, "/")
|
||||
return err
|
||||
})
|
||||
|
||||
wg.Wait()
|
||||
|
||||
select {
|
||||
case err := <-errc:
|
||||
c.Errorf("%v", err)
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
default:
|
||||
}
|
||||
|
||||
var b bytes.Buffer
|
||||
if err := frontPage.ExecuteTemplate(&b, "front", &data); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
io.Copy(w, &b)
|
||||
}
|
||||
|
||||
type frontPageData struct {
|
||||
Tables [4]clTable
|
||||
Timing [4]time.Duration
|
||||
|
||||
Reviewers []string
|
||||
UserIsReviewer bool
|
||||
|
||||
User, LogoutURL string // actual logged in user
|
||||
IsAdmin bool
|
||||
}
|
||||
|
||||
type clTable struct {
|
||||
Title string
|
||||
Assignable bool
|
||||
CLs []*CL
|
||||
}
|
||||
|
||||
var frontPage = template.Must(template.New("front").Funcs(template.FuncMap{
|
||||
"selected": func(a, b string) string {
|
||||
if a == b {
|
||||
return "selected"
|
||||
}
|
||||
return ""
|
||||
},
|
||||
"shortemail": func(s string) string {
|
||||
if i := strings.Index(s, "@"); i >= 0 {
|
||||
s = s[:i]
|
||||
}
|
||||
return s
|
||||
},
|
||||
}).Parse(`
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Go code reviews</title>
|
||||
<link rel="icon" type="image/png" href="/static/icon.png" />
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: Helvetica, sans-serif;
|
||||
}
|
||||
img#gopherstamp {
|
||||
float: right;
|
||||
height: auto;
|
||||
width: 250px;
|
||||
}
|
||||
h1, h2, h3 {
|
||||
color: #777;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
table {
|
||||
border-spacing: 0;
|
||||
}
|
||||
td {
|
||||
vertical-align: top;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
tr.unreplied td.email {
|
||||
border-left: 2px solid blue;
|
||||
}
|
||||
tr.pending td {
|
||||
background: #fc8;
|
||||
}
|
||||
tr.failed td {
|
||||
background: #f88;
|
||||
}
|
||||
tr.saved td {
|
||||
background: #8f8;
|
||||
}
|
||||
.cls {
|
||||
margin-top: 0;
|
||||
}
|
||||
a {
|
||||
color: blue;
|
||||
text-decoration: none; /* no link underline */
|
||||
}
|
||||
address {
|
||||
font-size: 10px;
|
||||
text-align: right;
|
||||
}
|
||||
.email {
|
||||
font-family: monospace;
|
||||
}
|
||||
</style>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<img id="gopherstamp" src="/static/gopherstamp.jpg" />
|
||||
<h1>Go code reviews</h1>
|
||||
|
||||
<table class="cls">
|
||||
{{range $i, $tbl := .Tables}}
|
||||
<tr><td colspan="5"><h3>{{$tbl.Title}}</h3></td></tr>
|
||||
{{if .CLs}}
|
||||
{{range $cl := .CLs}}
|
||||
<tr id="cl-{{$cl.Number}}" class="{{if not $i}}{{if not .Reviewed}}unreplied{{end}}{{end}}">
|
||||
<td class="email">{{$cl.DisplayOwner}}</td>
|
||||
<td>
|
||||
{{if $tbl.Assignable}}
|
||||
<select id="cl-rev-{{$cl.Number}}" {{if not $.UserIsReviewer}}disabled{{end}}>
|
||||
<option></option>
|
||||
{{range $.Reviewers}}
|
||||
<option {{selected . $cl.Reviewer}}>{{.}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$('#cl-rev-{{$cl.Number}}').change(function() {
|
||||
var r = $(this).val();
|
||||
var row = $('tr#cl-{{$cl.Number}}');
|
||||
row.addClass('pending');
|
||||
$.post('/assign', {
|
||||
'cl': '{{$cl.Number}}',
|
||||
'r': r
|
||||
}).success(function() {
|
||||
row.removeClass('pending');
|
||||
row.addClass('saved');
|
||||
}).error(function() {
|
||||
row.removeClass('pending');
|
||||
row.addClass('failed');
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{{end}}
|
||||
</td>
|
||||
<td>
|
||||
<a href="http://codereview.appspot.com/{{.Number}}/" title="{{ printf "%s" .Description}}">{{.Number}}: {{.FirstLineHTML}}</a>
|
||||
{{if and .LGTMs $tbl.Assignable}}<br /><span style="font-size: smaller;">LGTMs: {{.LGTMHTML}}</span>{{end}}
|
||||
{{if and .NotLGTMs $tbl.Assignable}}<br /><span style="font-size: smaller; color: #f74545;">NOT LGTMs: {{.NotLGTMHTML}}</span>{{end}}
|
||||
{{if .LastUpdateBy}}<br /><span style="font-size: smaller; color: #777777;">(<span title="{{.LastUpdateBy}}">{{.LastUpdateBy | shortemail}}</span>) {{.LastUpdate}}</span>{{end}}
|
||||
</td>
|
||||
<td title="Last modified">{{.ModifiedAgo}}</td>
|
||||
<td>{{if $.IsAdmin}}<a href="/update-cl?cl={{.Number}}" title="Update this CL">⟳</a>{{end}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{else}}
|
||||
<tr><td colspan="5"><em>none</em></td></tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</table>
|
||||
|
||||
<hr />
|
||||
<address>
|
||||
You are <span class="email">{{.User}}</span> · <a href="{{.LogoutURL}}">logout</a><br />
|
||||
datastore timing: {{range .Timing}} {{.}}{{end}}
|
||||
</address>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
`))
|
||||
47
misc/dashboard/codereview/dashboard/gc.go
Normal file
47
misc/dashboard/codereview/dashboard/gc.go
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package dashboard
|
||||
|
||||
// This file handles garbage collection of old CLs.
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"appengine"
|
||||
"appengine/datastore"
|
||||
)
|
||||
|
||||
func init() {
|
||||
http.HandleFunc("/gc", handleGC)
|
||||
}
|
||||
|
||||
func handleGC(w http.ResponseWriter, r *http.Request) {
|
||||
c := appengine.NewContext(r)
|
||||
|
||||
// Delete closed CLs that haven't been modified in 168 hours (7 days).
|
||||
cutoff := time.Now().Add(-168 * time.Hour)
|
||||
q := datastore.NewQuery("CL").
|
||||
Filter("Closed =", true).
|
||||
Filter("Modified <", cutoff).
|
||||
Limit(100).
|
||||
KeysOnly()
|
||||
keys, err := q.GetAll(c, nil)
|
||||
if err != nil {
|
||||
c.Errorf("GetAll failed for old CLs: %v", err)
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if len(keys) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if err := datastore.DeleteMulti(c, keys); err != nil {
|
||||
c.Errorf("DeleteMulti failed for old CLs: %v", err)
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
c.Infof("Deleted %d old CLs", len(keys))
|
||||
}
|
||||
68
misc/dashboard/codereview/dashboard/mail.go
Normal file
68
misc/dashboard/codereview/dashboard/mail.go
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package dashboard
|
||||
|
||||
// This file handles receiving mail.
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/mail"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"appengine"
|
||||
"appengine/datastore"
|
||||
)
|
||||
|
||||
func init() {
|
||||
http.HandleFunc("/_ah/mail/", handleMail)
|
||||
}
|
||||
|
||||
var subjectRegexp = regexp.MustCompile(`.*code review (\d+):.*`)
|
||||
|
||||
func handleMail(w http.ResponseWriter, r *http.Request) {
|
||||
c := appengine.NewContext(r)
|
||||
|
||||
defer r.Body.Close()
|
||||
msg, err := mail.ReadMessage(r.Body)
|
||||
if err != nil {
|
||||
c.Errorf("mail.ReadMessage: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
subj := msg.Header.Get("Subject")
|
||||
m := subjectRegexp.FindStringSubmatch(subj)
|
||||
if len(m) != 2 {
|
||||
c.Debugf("Subject %q did not match /%v/", subj, subjectRegexp)
|
||||
return
|
||||
}
|
||||
|
||||
c.Infof("Found issue %q", m[1])
|
||||
|
||||
// Track the MessageID.
|
||||
key := datastore.NewKey(c, "CL", m[1], 0, nil)
|
||||
err = datastore.RunInTransaction(c, func(c appengine.Context) error {
|
||||
cl := new(CL)
|
||||
err := datastore.Get(c, key, cl)
|
||||
if err != nil && err != datastore.ErrNoSuchEntity {
|
||||
return err
|
||||
}
|
||||
if err == datastore.ErrNoSuchEntity {
|
||||
// Must set sentinel values for time.Time fields
|
||||
// if this is a new entity.
|
||||
cl.Created = time.Unix(0, 0)
|
||||
cl.Modified = time.Unix(0, 0)
|
||||
}
|
||||
cl.LastMessageID = msg.Header.Get("Message-ID")
|
||||
_, err = datastore.Put(c, key, cl)
|
||||
return err
|
||||
}, nil)
|
||||
if err != nil {
|
||||
c.Errorf("datastore transaction failed: %v", err)
|
||||
}
|
||||
|
||||
// Update the CL after a delay to give Rietveld a chance to catch up.
|
||||
UpdateCLLater(c, m[1], 10*time.Second)
|
||||
}
|
||||
65
misc/dashboard/codereview/dashboard/people.go
Normal file
65
misc/dashboard/codereview/dashboard/people.go
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package dashboard
|
||||
|
||||
// This file handles identities of people.
|
||||
|
||||
import (
|
||||
"sort"
|
||||
)
|
||||
|
||||
var (
|
||||
emailToPerson = make(map[string]string) // email => person
|
||||
preferredEmail = make(map[string]string) // person => email
|
||||
personList []string
|
||||
)
|
||||
|
||||
func init() {
|
||||
// People we assume have golang.org and google.com accounts,
|
||||
// and prefer to use their golang.org address for code review.
|
||||
gophers := [...]string{
|
||||
"adg",
|
||||
"agl",
|
||||
"bradfitz",
|
||||
"campoy",
|
||||
"cshapiro",
|
||||
"dsymonds",
|
||||
"gri",
|
||||
"iant",
|
||||
"khr",
|
||||
"mpvl",
|
||||
"nigeltao",
|
||||
"r",
|
||||
"rsc",
|
||||
"sameer",
|
||||
}
|
||||
for _, p := range gophers {
|
||||
personList = append(personList, p)
|
||||
emailToPerson[p+"@golang.org"] = p
|
||||
emailToPerson[p+"@google.com"] = p
|
||||
preferredEmail[p] = p + "@golang.org"
|
||||
}
|
||||
// Other people.
|
||||
others := map[string]string{
|
||||
"adonovan": "adonovan@google.com",
|
||||
"brainman": "alex.brainman@gmail.com",
|
||||
"ality": "ality@pbrane.org",
|
||||
"dfc": "dave@cheney.net",
|
||||
"dvyukov": "dvyukov@google.com",
|
||||
"gustavo": "gustavo@niemeyer.net",
|
||||
"jsing": "jsing@google.com",
|
||||
"mikio": "mikioh.mikioh@gmail.com",
|
||||
"minux": "minux.ma@gmail.com",
|
||||
"remy": "remyoudompheng@gmail.com",
|
||||
"rminnich": "rminnich@gmail.com",
|
||||
}
|
||||
for p, e := range others {
|
||||
personList = append(personList, p)
|
||||
emailToPerson[e] = p
|
||||
preferredEmail[p] = e
|
||||
}
|
||||
|
||||
sort.Strings(personList)
|
||||
}
|
||||
25
misc/dashboard/codereview/index.yaml
Normal file
25
misc/dashboard/codereview/index.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
indexes:
|
||||
|
||||
- kind: CL
|
||||
properties:
|
||||
- name: Author
|
||||
- name: Modified
|
||||
direction: desc
|
||||
|
||||
- kind: CL
|
||||
properties:
|
||||
- name: Owner
|
||||
- name: Modified
|
||||
direction: desc
|
||||
|
||||
- kind: CL
|
||||
properties:
|
||||
- name: Closed
|
||||
- name: Modified
|
||||
direction: desc
|
||||
|
||||
- kind: CL
|
||||
properties:
|
||||
- name: Reviewer
|
||||
- name: Modified
|
||||
direction: desc
|
||||
4
misc/dashboard/codereview/queue.yaml
Normal file
4
misc/dashboard/codereview/queue.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
queue:
|
||||
- name: update-cl
|
||||
rate: 12/m
|
||||
bucket_size: 1
|
||||
BIN
misc/dashboard/codereview/static/gopherstamp.jpg
Normal file
BIN
misc/dashboard/codereview/static/gopherstamp.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
misc/dashboard/codereview/static/icon.png
Normal file
BIN
misc/dashboard/codereview/static/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 412 B |
@@ -1,5 +1,5 @@
|
||||
For information about plugins and other support for Go in editors and shells,
|
||||
see this page on the Go Wiki:
|
||||
|
||||
https://golang.org/wiki/IDEsAndTextEditorPlugins
|
||||
https://code.google.com/p/go-wiki/wiki/IDEsAndTextEditorPlugins
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
Go on iOS
|
||||
=========
|
||||
|
||||
To build a cross compiling toolchain for iOS on OS X, first modify clangwrap.sh
|
||||
in misc/ios to match your setup. And then run:
|
||||
|
||||
GOARM=7 CGO_ENABLED=1 GOARCH=arm CC_FOR_TARGET=`pwd`/../misc/ios/clangwrap.sh \
|
||||
CXX_FOR_TARGET=`pwd`/../misc/ios/clangwrap.sh ./make.bash
|
||||
|
||||
To build a program, use the normal go build command:
|
||||
|
||||
CGO_ENABLED=1 GOARCH=arm go build import/path
|
||||
|
||||
To run a program on an iDevice, first make sure you have a valid developer
|
||||
certificate and have setup your iDevice properly to run apps signed by your
|
||||
developer certificate. Then install https://github.com/phonegap/ios-deploy.
|
||||
At a first step, you can try building the famous hello world program to run
|
||||
on your test device.
|
||||
(The needed files are provided at https://github.com/minux/go-ios-examples.)
|
||||
|
||||
# assume your program binary is helloworld.go, build it into the
|
||||
# example hello.app bundle.
|
||||
CGO_ENABLED=1 GOARCH=arm go build -o hello.app/hello helloworld.go
|
||||
# sign the executable using your developer certificate
|
||||
codesign -f -s "iPhone Developer" --entitlements hello.app/Entitlements.plist hello.app/hello
|
||||
# run the program inside lldb on iDevice, run `ios-deploy` for more
|
||||
# command options
|
||||
ios-deploy --debug --uninstall --bundle hello.app
|
||||
# Depending on your ios-deploy version, you might need to enter "run"
|
||||
# into lldb to run your program, and its output will be shown by lldb.
|
||||
|
||||
Notes:
|
||||
- A dummy hello.app bundle is provided in this directory to help you get started.
|
||||
- Running the program on an iDevice requires code sign and thus external linking,
|
||||
if your program uses cgo, then it will automatically use external linking.
|
||||
However, if your program does not use cgo, please make sure to add
|
||||
import _ "runtime/cgo"
|
||||
so that external linking will be used.
|
||||
|
||||
Known issues
|
||||
============
|
||||
- crypto/x509 won't build, I don't yet know how to get system root on iOS.
|
||||
- Because I still want to be able to do native build, CGO_ENABLED=1 is not the
|
||||
default, yet.
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
# This uses the latest available iOS SDK, which is recommended.
|
||||
# To select a specific SDK, run 'xcodebuild -showsdks'
|
||||
# to see the available SDKs and replace iphoneos with one of them.
|
||||
SDK=iphoneos
|
||||
SDK_PATH=`xcrun --sdk $SDK --show-sdk-path`
|
||||
export IPHONEOS_DEPLOYMENT_TARGET=5.1
|
||||
# cmd/cgo doesn't support llvm-gcc-4.2, so we have to use clang.
|
||||
CLANG=`xcrun --sdk $SDK --find clang`
|
||||
exec $CLANG -arch armv7 -isysroot $SDK_PATH "$@"
|
||||
@@ -30,16 +30,15 @@ import (
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"code.google.com/p/goauth2/oauth"
|
||||
storage "code.google.com/p/google-api-go-client/storage/v1"
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/oauth2/google"
|
||||
)
|
||||
|
||||
var (
|
||||
tag = flag.String("tag", "", "git revision to check out")
|
||||
toolTag = flag.String("tool", defaultToolTag, "go.tools revision to check out")
|
||||
tag = flag.String("tag", "release", "mercurial tag to check out")
|
||||
toolTag = flag.String("tool", defaultToolTag, "go.tools tag to check out")
|
||||
tourTag = flag.String("tour", defaultTourTag, "go-tour tag to check out")
|
||||
repo = flag.String("repo", "https://go.googlesource.com/go", "repo URL")
|
||||
repo = flag.String("repo", "https://code.google.com/p/go", "repo URL")
|
||||
verbose = flag.Bool("v", false, "verbose output")
|
||||
upload = flag.Bool("upload", false, "upload resulting files to Google Code")
|
||||
addLabel = flag.String("label", "", "additional label to apply to file when uploading")
|
||||
@@ -81,9 +80,9 @@ var preBuildCleanFiles = []string{
|
||||
}
|
||||
|
||||
var cleanFiles = []string{
|
||||
".git",
|
||||
".gitignore",
|
||||
".gitattributes",
|
||||
".hg",
|
||||
".hgtags",
|
||||
".hgignore",
|
||||
"VERSION.cache",
|
||||
}
|
||||
|
||||
@@ -206,10 +205,6 @@ func main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if *tag == "" {
|
||||
fmt.Fprintln(os.Stderr, "you must specify a -tag")
|
||||
os.Exit(2)
|
||||
}
|
||||
if err := b.Do(); err != nil {
|
||||
log.Printf("%s: %v", targ, err)
|
||||
ok = false
|
||||
@@ -241,11 +236,11 @@ func (b *Build) Do() error {
|
||||
b.gopath = work
|
||||
|
||||
// Clone Go distribution and update to tag.
|
||||
_, err = b.run(work, "git", "clone", *repo, b.root)
|
||||
_, err = b.hgCmd(work, "clone", *repo, b.root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = b.run(b.root, "git", "checkout", *tag)
|
||||
_, err = b.hgCmd(b.root, "update", *tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -277,27 +272,13 @@ func (b *Build) Do() error {
|
||||
if b.OS == "windows" {
|
||||
goCmd += ".exe"
|
||||
}
|
||||
// Because on release branches, go install -a std is a NOP,
|
||||
// we have to resort to delete pkg/$GOOS_$GOARCH, install -race,
|
||||
// and then reinstall std so that we're not left with a slower,
|
||||
// race-enabled cmd/go, etc.
|
||||
goPkg := filepath.Join(b.root, "pkg", b.OS+"_"+b.Arch)
|
||||
err = os.RemoveAll(goPkg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = b.run(src, goCmd, "tool", "dist", "install", "runtime")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = b.run(src, goCmd, "install", "-race", "std")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = b.run(src, goCmd, "install", "std")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Re-install std without -race, so that we're not left
|
||||
// with a slower, race-enabled cmd/go, etc.
|
||||
_, err = b.run(src, goCmd, "install", "-a", "std")
|
||||
// Re-building go command leaves old versions of go.exe as go.exe~ on windows.
|
||||
// See (*builder).copyFile in $GOROOT/src/cmd/go/build.go for details.
|
||||
// Remove it manually.
|
||||
@@ -524,15 +505,30 @@ func (b *Build) extras() error {
|
||||
}
|
||||
|
||||
func (b *Build) get(repoPath, revision string) error {
|
||||
// Fetch the packages (without building/installing).
|
||||
_, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"),
|
||||
"get", "-d", repoPath+"/...")
|
||||
if err != nil {
|
||||
return err
|
||||
dest := filepath.Join(b.gopath, "src", filepath.FromSlash(repoPath))
|
||||
|
||||
if strings.HasPrefix(repoPath, "golang.org/x/") {
|
||||
// For sub-repos, fetch the old Mercurial repo; bypass "go get".
|
||||
// DO NOT import this special case into the git tree.
|
||||
|
||||
if err := os.MkdirAll(filepath.Dir(dest), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
repo := strings.Replace(repoPath, "golang.org/x/", "https://code.google.com/p/go.", 1)
|
||||
if _, err := b.run(b.gopath, "hg", "clone", repo, dest); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Fetch the packages (without building/installing).
|
||||
_, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"),
|
||||
"get", "-d", repoPath+"/...")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Update the repo to the specified revision.
|
||||
dest := filepath.Join(b.gopath, "src", filepath.FromSlash(repoPath))
|
||||
var err error
|
||||
switch {
|
||||
case exists(filepath.Join(dest, ".git")):
|
||||
_, err = b.run(dest, "git", "checkout", revision)
|
||||
@@ -639,6 +635,10 @@ func ext() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (b *Build) hgCmd(dir string, args ...string) ([]byte, error) {
|
||||
return b.run(dir, "hg", append([]string{"--config", "extensions.codereview=!"}, args...)...)
|
||||
}
|
||||
|
||||
func (b *Build) run(dir, name string, args ...string) ([]byte, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
absName, err := lookPath(name)
|
||||
@@ -736,7 +736,6 @@ func (b *Build) Upload(version string, filename string) error {
|
||||
OS: b.OS,
|
||||
Arch: b.Arch,
|
||||
Checksum: sum,
|
||||
Size: len(file),
|
||||
Kind: kind,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -761,50 +760,43 @@ type File struct {
|
||||
Arch string
|
||||
Version string
|
||||
Checksum string `datastore:",noindex"`
|
||||
Size int `datastore:",noindex"`
|
||||
Kind string // "archive", "installer", "source"
|
||||
}
|
||||
|
||||
func setupOAuthClient() error {
|
||||
config := &oauth2.Config{
|
||||
ClientID: "999119582588-h7kpj5pcm6d9solh5lgrbusmvvk4m9dn.apps.googleusercontent.com",
|
||||
config := &oauth.Config{
|
||||
ClientId: "999119582588-h7kpj5pcm6d9solh5lgrbusmvvk4m9dn.apps.googleusercontent.com",
|
||||
ClientSecret: "8YLFgOhXIELWbO-NtF3iqIQz",
|
||||
Endpoint: google.Endpoint,
|
||||
Scopes: []string{storage.DevstorageRead_writeScope},
|
||||
Scope: storage.DevstorageRead_writeScope,
|
||||
AuthURL: "https://accounts.google.com/o/oauth2/auth",
|
||||
TokenURL: "https://accounts.google.com/o/oauth2/token",
|
||||
TokenCache: oauth.CacheFile(*tokenCache),
|
||||
RedirectURL: "oob",
|
||||
}
|
||||
url := config.AuthCodeURL("junk")
|
||||
fmt.Println("Visit the following URL, obtain an authentication" +
|
||||
"code, and enter it below.")
|
||||
fmt.Println(url)
|
||||
fmt.Print("Enter authentication code: ")
|
||||
code := ""
|
||||
if _, err := fmt.Scan(&code); err != nil {
|
||||
return err
|
||||
transport := &oauth.Transport{Config: config}
|
||||
if token, err := config.TokenCache.Token(); err != nil {
|
||||
url := transport.Config.AuthCodeURL("")
|
||||
fmt.Println("Visit the following URL, obtain an authentication" +
|
||||
"code, and enter it below.")
|
||||
fmt.Println(url)
|
||||
fmt.Print("Enter authentication code: ")
|
||||
code := ""
|
||||
if _, err := fmt.Scan(&code); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := transport.Exchange(code); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
transport.Token = token
|
||||
}
|
||||
tok, err := config.Exchange(oauth2.NoContext, code)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
oauthClient = config.Client(oauth2.NoContext, tok)
|
||||
oauthClient = transport.Client()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Build) clean(files []string) error {
|
||||
for _, name := range files {
|
||||
path := filepath.Join(b.root, name)
|
||||
var err error
|
||||
if b.OS == "windows" {
|
||||
// Git sets some of its packfiles as 'read only',
|
||||
// so os.RemoveAll will fail for the ".git" directory.
|
||||
// Instead, shell out to cmd's 'del' subcommand.
|
||||
cmd := exec.Command("cmd.exe", "/C", "del", "/Q", "/F", "/S", path)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err = cmd.Run()
|
||||
} else {
|
||||
err = os.RemoveAll(path)
|
||||
}
|
||||
err := os.RemoveAll(filepath.Join(b.root, name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1034,11 +1026,6 @@ var hgTool = tool{
|
||||
},
|
||||
}
|
||||
|
||||
var gitTool = tool{
|
||||
"http://git-scm.com/download/win",
|
||||
[]string{`C:\Program Files\Git`, `C:\Program Files (x86)\Git`},
|
||||
}
|
||||
|
||||
var gccTool = tool{
|
||||
"Mingw gcc; http://sourceforge.net/projects/mingw/files/Installer/mingw-get-inst/",
|
||||
[]string{`C:\Mingw\bin`},
|
||||
@@ -1050,7 +1037,6 @@ var windowsDeps = map[string]tool{
|
||||
"candle": wixTool,
|
||||
"light": wixTool,
|
||||
"cmd": {"Windows cmd.exe", nil},
|
||||
"git": gitTool,
|
||||
"hg": hgTool,
|
||||
}
|
||||
|
||||
|
||||
@@ -10,31 +10,14 @@ usr src=../misc/nacl/testdata
|
||||
go src=..
|
||||
src
|
||||
cmd
|
||||
asm
|
||||
internal
|
||||
asm
|
||||
testdata
|
||||
+
|
||||
internal
|
||||
objfile
|
||||
objfile.go
|
||||
rsc.io
|
||||
arm
|
||||
armasm
|
||||
testdata
|
||||
+
|
||||
x86
|
||||
x86asm
|
||||
testdata
|
||||
+
|
||||
gofmt
|
||||
gofmt.go
|
||||
gofmt_test.go
|
||||
testdata
|
||||
+
|
||||
link
|
||||
testdata
|
||||
+
|
||||
archive
|
||||
tar
|
||||
testdata
|
||||
|
||||
@@ -10,7 +10,7 @@ import "testing"
|
||||
// as expected.
|
||||
func TestRead(t *testing.T) {
|
||||
f := Fopen("file_test.go", "r")
|
||||
if f.Swigcptr() == 0 {
|
||||
if f == nil {
|
||||
t.Fatal("fopen failed")
|
||||
}
|
||||
if Fgetc(f) != '/' || Fgetc(f) != '/' || Fgetc(f) != ' ' || Fgetc(f) != 'C' {
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
This directory contains helper file for trace viewer (go tool trace).
|
||||
|
||||
trace_viewer_lean.html was generated following instructions in:
|
||||
https://github.com/google/trace-viewer/wiki/Embedding
|
||||
on revision 895aa74558d19d91906fb720df6458244ef160c6 using:
|
||||
trace-viewer$ ./vulcanize_trace_viewer --config=lean
|
||||
File diff suppressed because one or more lines are too long
@@ -11,7 +11,7 @@ set -e
|
||||
ulimit -c 0 # no core files
|
||||
|
||||
if [ ! -f make.bash ]; then
|
||||
echo 'androidtest.bash must be run from $GOROOT/src' 1>&2
|
||||
echo 'nacl.bash must be run from $GOROOT/src' 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -38,15 +38,14 @@ GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH go build \
|
||||
#
|
||||
# The adb sync command will sync either the /system or /data
|
||||
# directories of an android device from a similar directory
|
||||
# on the host. We copy the files required for running tests under
|
||||
# /data/local/tmp/goroot. The adb sync command does not follow
|
||||
# symlinks so we have to copy.
|
||||
# on the host. So we fake one with symlinks to push the GOROOT
|
||||
# into a subdirectory of /data.
|
||||
export ANDROID_PRODUCT_OUT=/tmp/androidtest-$$
|
||||
FAKE_GOROOT=$ANDROID_PRODUCT_OUT/data/local/tmp/goroot
|
||||
mkdir -p $FAKE_GOROOT
|
||||
cp -a "${GOROOT}/src" "${FAKE_GOROOT}/"
|
||||
cp -a "${GOROOT}/test" "${FAKE_GOROOT}/"
|
||||
cp -a "${GOROOT}/lib" "${FAKE_GOROOT}/"
|
||||
ln -s $GOROOT/src $FAKE_GOROOT/src
|
||||
ln -s $GOROOT/test $FAKE_GOROOT/test
|
||||
ln -s $GOROOT/lib $FAKE_GOROOT/lib
|
||||
echo '# Syncing test files to android device'
|
||||
time adb sync data &> /dev/null
|
||||
echo ''
|
||||
|
||||
@@ -31,7 +31,6 @@ func Example() {
|
||||
for _, file := range files {
|
||||
hdr := &tar.Header{
|
||||
Name: file.Name,
|
||||
Mode: 0600,
|
||||
Size: int64(len(file.Body)),
|
||||
}
|
||||
if err := tw.WriteHeader(hdr); err != nil {
|
||||
|
||||
@@ -85,8 +85,6 @@ const (
|
||||
func NewReader(r io.Reader) *Reader { return &Reader{r: r} }
|
||||
|
||||
// Next advances to the next entry in the tar archive.
|
||||
//
|
||||
// io.EOF is returned at the end of the input.
|
||||
func (tr *Reader) Next() (*Header, error) {
|
||||
var hdr *Header
|
||||
if tr.err == nil {
|
||||
|
||||
@@ -144,39 +144,6 @@ func (b *Reader) Peek(n int) ([]byte, error) {
|
||||
return b.buf[b.r : b.r+n], err
|
||||
}
|
||||
|
||||
// Discard skips the next n bytes, returning the number of bytes discarded.
|
||||
//
|
||||
// If Discard skips fewer than n bytes, it also returns an error.
|
||||
// If 0 <= n <= b.Buffered(), Discard is guaranteed to succeed without
|
||||
// reading from the underlying io.Reader.
|
||||
func (b *Reader) Discard(n int) (discarded int, err error) {
|
||||
if n < 0 {
|
||||
return 0, ErrNegativeCount
|
||||
}
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
remain := n
|
||||
for {
|
||||
skip := b.Buffered()
|
||||
if skip == 0 {
|
||||
b.fill()
|
||||
skip = b.Buffered()
|
||||
}
|
||||
if skip > remain {
|
||||
skip = remain
|
||||
}
|
||||
b.r += skip
|
||||
remain -= skip
|
||||
if remain == 0 {
|
||||
return n, nil
|
||||
}
|
||||
if b.err != nil {
|
||||
return n - remain, b.readErr()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read reads data into p.
|
||||
// It returns the number of bytes read into p.
|
||||
// It calls Read at most once on the underlying Reader,
|
||||
|
||||
@@ -1268,135 +1268,6 @@ func TestWriterReset(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestReaderDiscard(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
r io.Reader
|
||||
bufSize int // 0 means 16
|
||||
peekSize int
|
||||
|
||||
n int // input to Discard
|
||||
|
||||
want int // from Discard
|
||||
wantErr error // from Discard
|
||||
|
||||
wantBuffered int
|
||||
}{
|
||||
{
|
||||
name: "normal case",
|
||||
r: strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
|
||||
peekSize: 16,
|
||||
n: 6,
|
||||
want: 6,
|
||||
wantBuffered: 10,
|
||||
},
|
||||
{
|
||||
name: "discard causing read",
|
||||
r: strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
|
||||
n: 6,
|
||||
want: 6,
|
||||
wantBuffered: 10,
|
||||
},
|
||||
{
|
||||
name: "discard all without peek",
|
||||
r: strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
|
||||
n: 26,
|
||||
want: 26,
|
||||
wantBuffered: 0,
|
||||
},
|
||||
{
|
||||
name: "discard more than end",
|
||||
r: strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
|
||||
n: 27,
|
||||
want: 26,
|
||||
wantErr: io.EOF,
|
||||
wantBuffered: 0,
|
||||
},
|
||||
// Any error from filling shouldn't show up until we
|
||||
// get past the valid bytes. Here we return we return 5 valid bytes at the same time
|
||||
// as an error, but test that we don't see the error from Discard.
|
||||
{
|
||||
name: "fill error, discard less",
|
||||
r: newScriptedReader(func(p []byte) (n int, err error) {
|
||||
if len(p) < 5 {
|
||||
panic("unexpected small read")
|
||||
}
|
||||
return 5, errors.New("5-then-error")
|
||||
}),
|
||||
n: 4,
|
||||
want: 4,
|
||||
wantErr: nil,
|
||||
wantBuffered: 1,
|
||||
},
|
||||
{
|
||||
name: "fill error, discard equal",
|
||||
r: newScriptedReader(func(p []byte) (n int, err error) {
|
||||
if len(p) < 5 {
|
||||
panic("unexpected small read")
|
||||
}
|
||||
return 5, errors.New("5-then-error")
|
||||
}),
|
||||
n: 5,
|
||||
want: 5,
|
||||
wantErr: nil,
|
||||
wantBuffered: 0,
|
||||
},
|
||||
{
|
||||
name: "fill error, discard more",
|
||||
r: newScriptedReader(func(p []byte) (n int, err error) {
|
||||
if len(p) < 5 {
|
||||
panic("unexpected small read")
|
||||
}
|
||||
return 5, errors.New("5-then-error")
|
||||
}),
|
||||
n: 6,
|
||||
want: 5,
|
||||
wantErr: errors.New("5-then-error"),
|
||||
wantBuffered: 0,
|
||||
},
|
||||
// Discard of 0 shouldn't cause a read:
|
||||
{
|
||||
name: "discard zero",
|
||||
r: newScriptedReader(), // will panic on Read
|
||||
n: 0,
|
||||
want: 0,
|
||||
wantErr: nil,
|
||||
wantBuffered: 0,
|
||||
},
|
||||
{
|
||||
name: "discard negative",
|
||||
r: newScriptedReader(), // will panic on Read
|
||||
n: -1,
|
||||
want: 0,
|
||||
wantErr: ErrNegativeCount,
|
||||
wantBuffered: 0,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
br := NewReaderSize(tt.r, tt.bufSize)
|
||||
if tt.peekSize > 0 {
|
||||
peekBuf, err := br.Peek(tt.peekSize)
|
||||
if err != nil {
|
||||
t.Errorf("%s: Peek(%d): %v", tt.name, tt.peekSize, err)
|
||||
continue
|
||||
}
|
||||
if len(peekBuf) != tt.peekSize {
|
||||
t.Errorf("%s: len(Peek(%d)) = %v; want %v", tt.name, tt.peekSize, len(peekBuf), tt.peekSize)
|
||||
continue
|
||||
}
|
||||
}
|
||||
discarded, err := br.Discard(tt.n)
|
||||
if ge, we := fmt.Sprint(err), fmt.Sprint(tt.wantErr); discarded != tt.want || ge != we {
|
||||
t.Errorf("%s: Discard(%d) = (%v, %v); want (%v, %v)", tt.name, tt.n, discarded, ge, tt.want, we)
|
||||
continue
|
||||
}
|
||||
if bn := br.Buffered(); bn != tt.wantBuffered {
|
||||
t.Errorf("%s: after Discard, Buffered = %d; want %d", tt.name, bn, tt.wantBuffered)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have.
|
||||
type onlyReader struct {
|
||||
io.Reader
|
||||
@@ -1407,23 +1278,6 @@ type onlyWriter struct {
|
||||
io.Writer
|
||||
}
|
||||
|
||||
// A scriptedReader is an io.Reader that executes its steps sequentially.
|
||||
type scriptedReader []func(p []byte) (n int, err error)
|
||||
|
||||
func (sr *scriptedReader) Read(p []byte) (n int, err error) {
|
||||
if len(*sr) == 0 {
|
||||
panic("too many Read calls on scripted Reader. No steps remain.")
|
||||
}
|
||||
step := (*sr)[0]
|
||||
*sr = (*sr)[1:]
|
||||
return step(p)
|
||||
}
|
||||
|
||||
func newScriptedReader(steps ...func(p []byte) (n int, err error)) io.Reader {
|
||||
sr := scriptedReader(steps)
|
||||
return &sr
|
||||
}
|
||||
|
||||
func BenchmarkReaderCopyOptimal(b *testing.B) {
|
||||
// Optimal case is where the underlying reader implements io.WriterTo
|
||||
srcBuf := bytes.NewBuffer(make([]byte, 8192))
|
||||
|
||||
@@ -23,7 +23,7 @@ func equalPortable(a, b []byte) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// explode splits s into a slice of UTF-8 sequences, one per Unicode code point (still slices of bytes),
|
||||
// explode splits s into a slice of UTF-8 sequences, one per Unicode character (still slices of bytes),
|
||||
// up to a maximum of n byte slices. Invalid UTF-8 sequences are chopped into individual bytes.
|
||||
func explode(s []byte, n int) [][]byte {
|
||||
if n <= 0 {
|
||||
@@ -47,7 +47,6 @@ func explode(s []byte, n int) [][]byte {
|
||||
}
|
||||
|
||||
// Count counts the number of non-overlapping instances of sep in s.
|
||||
// If sep is an empty slice, Count returns 1 + the number of Unicode code points in s.
|
||||
func Count(s, sep []byte) int {
|
||||
n := len(sep)
|
||||
if n == 0 {
|
||||
|
||||
@@ -21,4 +21,4 @@ func Equal(a, b []byte) bool // ../runtime/asm_$GOARCH.s
|
||||
// Compare returns an integer comparing two byte slices lexicographically.
|
||||
// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
|
||||
// A nil argument is equivalent to an empty slice.
|
||||
func Compare(a, b []byte) int // ../runtime/noasm.go or ../runtime/asm_{386,amd64}.s
|
||||
func Compare(a, b []byte) int // ../runtime/noasm_arm.goc or ../runtime/asm_{386,amd64}.s
|
||||
|
||||
10
src/cmd/5a/Makefile
Normal file
10
src/cmd/5a/Makefile
Normal file
@@ -0,0 +1,10 @@
|
||||
# Copyright 2012 The Go Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
include ../../Make.dist
|
||||
|
||||
install: y.tab.h
|
||||
|
||||
y.tab.h: a.y
|
||||
LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y a.y
|
||||
169
src/cmd/5a/a.h
Normal file
169
src/cmd/5a/a.h
Normal file
@@ -0,0 +1,169 @@
|
||||
// Inferno utils/5a/a.h
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/5a/a.h
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include <bio.h>
|
||||
#include <link.h>
|
||||
#include "../5l/5.out.h"
|
||||
|
||||
#ifndef EXTERN
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#undef getc
|
||||
#undef ungetc
|
||||
#undef BUFSIZ
|
||||
|
||||
#define getc ccgetc
|
||||
#define ungetc ccungetc
|
||||
|
||||
typedef struct Sym Sym;
|
||||
typedef struct Io Io;
|
||||
|
||||
#define MAXALIGN 7
|
||||
#define FPCHIP 1
|
||||
#define NSYMB 8192
|
||||
#define BUFSIZ 8192
|
||||
#define HISTSZ 20
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
#define IGN (-2)
|
||||
#define GETC() ((--fi.c < 0)? filbuf(): *fi.p++ & 0xff)
|
||||
#define NHASH 503
|
||||
#define STRINGSZ 200
|
||||
#define NMACRO 10
|
||||
|
||||
struct Sym
|
||||
{
|
||||
Sym* link;
|
||||
char* macro;
|
||||
int32 value;
|
||||
ushort type;
|
||||
char *name;
|
||||
char sym;
|
||||
};
|
||||
#define S ((Sym*)0)
|
||||
|
||||
EXTERN struct
|
||||
{
|
||||
char* p;
|
||||
int c;
|
||||
} fi;
|
||||
|
||||
struct Io
|
||||
{
|
||||
Io* link;
|
||||
char b[BUFSIZ];
|
||||
char* p;
|
||||
short c;
|
||||
short f;
|
||||
};
|
||||
#define I ((Io*)0)
|
||||
|
||||
enum
|
||||
{
|
||||
CLAST,
|
||||
CMACARG,
|
||||
CMACRO,
|
||||
CPREPROC,
|
||||
|
||||
Always = 14,
|
||||
};
|
||||
|
||||
EXTERN int debug[256];
|
||||
EXTERN Sym* hash[NHASH];
|
||||
EXTERN char** Dlist;
|
||||
EXTERN int nDlist;
|
||||
EXTERN int newflag;
|
||||
EXTERN char* hunk;
|
||||
EXTERN char** include;
|
||||
EXTERN Io* iofree;
|
||||
EXTERN Io* ionext;
|
||||
EXTERN Io* iostack;
|
||||
EXTERN int32 lineno;
|
||||
EXTERN int nerrors;
|
||||
EXTERN int32 nhunk;
|
||||
EXTERN int ninclude;
|
||||
EXTERN int32 nsymb;
|
||||
EXTERN Addr nullgen;
|
||||
EXTERN char* outfile;
|
||||
EXTERN int pass;
|
||||
EXTERN int32 pc;
|
||||
EXTERN int peekc;
|
||||
EXTERN int32 stmtline;
|
||||
EXTERN int sym;
|
||||
EXTERN char* symb;
|
||||
EXTERN int thechar;
|
||||
EXTERN char* thestring;
|
||||
EXTERN int32 thunk;
|
||||
EXTERN Biobuf obuf;
|
||||
EXTERN Link* ctxt;
|
||||
EXTERN Biobuf bstdout;
|
||||
|
||||
void* alloc(int32);
|
||||
void* allocn(void*, int32, int32);
|
||||
void ensuresymb(int32);
|
||||
void errorexit(void);
|
||||
void pushio(void);
|
||||
void newio(void);
|
||||
void newfile(char*, int);
|
||||
Sym* slookup(char*);
|
||||
Sym* lookup(void);
|
||||
void syminit(Sym*);
|
||||
int32 yylex(void);
|
||||
int getc(void);
|
||||
int getnsc(void);
|
||||
void unget(int);
|
||||
int escchar(int);
|
||||
void cinit(void);
|
||||
void pinit(char*);
|
||||
void cclean(void);
|
||||
int isreg(Addr*);
|
||||
void outcode(int, int, Addr*, int, Addr*);
|
||||
int filbuf(void);
|
||||
Sym* getsym(void);
|
||||
void domacro(void);
|
||||
void macund(void);
|
||||
void macdef(void);
|
||||
void macexpand(Sym*, char*);
|
||||
void macinc(void);
|
||||
void maclin(void);
|
||||
void macprag(void);
|
||||
void macif(int);
|
||||
void macend(void);
|
||||
void dodefine(char*);
|
||||
void prfile(int32);
|
||||
void linehist(char*, int);
|
||||
void gethunk(void);
|
||||
void yyerror(char*, ...);
|
||||
int yyparse(void);
|
||||
void setinclude(char*);
|
||||
int assemble(char*);
|
||||
void listinit(void);
|
||||
418
src/cmd/5a/a.y
418
src/cmd/5a/a.y
@@ -29,23 +29,20 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
%{
|
||||
package main
|
||||
|
||||
import (
|
||||
"cmd/internal/asm"
|
||||
"cmd/internal/obj"
|
||||
. "cmd/internal/obj/arm"
|
||||
)
|
||||
#include <u.h>
|
||||
#include <stdio.h> /* if we don't, bison will, and a.h re-#defines getc */
|
||||
#include <libc.h>
|
||||
#include "a.h"
|
||||
#include "../../runtime/funcdata.h"
|
||||
%}
|
||||
|
||||
%union {
|
||||
sym *asm.Sym
|
||||
lval int32
|
||||
dval float64
|
||||
sval string
|
||||
addr obj.Addr
|
||||
%union
|
||||
{
|
||||
Sym *sym;
|
||||
int32 lval;
|
||||
double dval;
|
||||
char sval[8];
|
||||
Addr addr;
|
||||
}
|
||||
|
||||
%left '|'
|
||||
%left '^'
|
||||
%left '&'
|
||||
@@ -59,44 +56,46 @@ import (
|
||||
%token <lval> LTYPEL LTYPEM LTYPEN LTYPEBX LTYPEPLD
|
||||
%token <lval> LCONST LSP LSB LFP LPC
|
||||
%token <lval> LTYPEX LTYPEPC LTYPEF LR LREG LF LFREG LC LCREG LPSR LFCR
|
||||
%token <lval> LCOND LS LAT LGLOBL
|
||||
%token <lval> LCOND LS LAT
|
||||
%token <dval> LFCONST
|
||||
%token <sval> LSCONST
|
||||
%token <sym> LNAME LLAB LVAR
|
||||
%type <lval> con expr oexpr pointer offset sreg spreg creg
|
||||
%type <lval> rcon cond reglist
|
||||
%type <addr> gen rel reg regreg freg shift fcon frcon textsize
|
||||
%type <addr> gen rel reg regreg freg shift fcon frcon
|
||||
%type <addr> imm ximm name oreg ireg nireg ioreg imsr
|
||||
%%
|
||||
prog:
|
||||
| prog
|
||||
{
|
||||
stmtline = asm.Lineno;
|
||||
stmtline = lineno;
|
||||
}
|
||||
line
|
||||
|
||||
line:
|
||||
LNAME ':'
|
||||
LLAB ':'
|
||||
{
|
||||
$1 = asm.LabelLookup($1);
|
||||
if $1.Type == LLAB && $1.Value != int64(asm.PC) {
|
||||
yyerror("redeclaration of %s", $1.Labelname)
|
||||
}
|
||||
$1.Type = LLAB;
|
||||
$1.Value = int64(asm.PC)
|
||||
if($1->value != pc)
|
||||
yyerror("redeclaration of %s", $1->name);
|
||||
$1->value = pc;
|
||||
}
|
||||
line
|
||||
| LNAME ':'
|
||||
{
|
||||
$1->type = LLAB;
|
||||
$1->value = pc;
|
||||
}
|
||||
line
|
||||
| LNAME '=' expr ';'
|
||||
{
|
||||
$1.Type = LVAR;
|
||||
$1.Value = int64($3);
|
||||
$1->type = LVAR;
|
||||
$1->value = $3;
|
||||
}
|
||||
| LVAR '=' expr ';'
|
||||
{
|
||||
if $1.Value != int64($3) {
|
||||
yyerror("redeclaration of %s", $1.Name)
|
||||
}
|
||||
$1.Value = int64($3);
|
||||
if($1->value != $3)
|
||||
yyerror("redeclaration of %s", $1->name);
|
||||
$1->value = $3;
|
||||
}
|
||||
| ';'
|
||||
| inst ';'
|
||||
@@ -116,53 +115,53 @@ inst:
|
||||
}
|
||||
| LTYPE1 cond imsr ',' reg
|
||||
{
|
||||
outcode($1, $2, &$3, 0, &$5);
|
||||
outcode($1, $2, &$3, NREG, &$5);
|
||||
}
|
||||
/*
|
||||
* MVN
|
||||
*/
|
||||
| LTYPE2 cond imsr ',' reg
|
||||
{
|
||||
outcode($1, $2, &$3, 0, &$5);
|
||||
outcode($1, $2, &$3, NREG, &$5);
|
||||
}
|
||||
/*
|
||||
* MOVW
|
||||
*/
|
||||
| LTYPE3 cond gen ',' gen
|
||||
{
|
||||
outcode($1, $2, &$3, 0, &$5);
|
||||
outcode($1, $2, &$3, NREG, &$5);
|
||||
}
|
||||
/*
|
||||
* B/BL
|
||||
*/
|
||||
| LTYPE4 cond comma rel
|
||||
{
|
||||
outcode($1, $2, &nullgen, 0, &$4);
|
||||
outcode($1, $2, &nullgen, NREG, &$4);
|
||||
}
|
||||
| LTYPE4 cond comma nireg
|
||||
{
|
||||
outcode($1, $2, &nullgen, 0, &$4);
|
||||
outcode($1, $2, &nullgen, NREG, &$4);
|
||||
}
|
||||
/*
|
||||
* BX
|
||||
*/
|
||||
| LTYPEBX comma ireg
|
||||
{
|
||||
outcode($1, Always, &nullgen, 0, &$3);
|
||||
outcode($1, Always, &nullgen, NREG, &$3);
|
||||
}
|
||||
/*
|
||||
* BEQ
|
||||
*/
|
||||
| LTYPE5 comma rel
|
||||
{
|
||||
outcode($1, Always, &nullgen, 0, &$3);
|
||||
outcode($1, Always, &nullgen, NREG, &$3);
|
||||
}
|
||||
/*
|
||||
* SWI
|
||||
*/
|
||||
| LTYPE6 cond comma gen
|
||||
{
|
||||
outcode($1, $2, &nullgen, 0, &$4);
|
||||
outcode($1, $2, &nullgen, NREG, &$4);
|
||||
}
|
||||
/*
|
||||
* CMP
|
||||
@@ -176,114 +175,96 @@ inst:
|
||||
*/
|
||||
| LTYPE8 cond ioreg ',' '[' reglist ']'
|
||||
{
|
||||
var g obj.Addr
|
||||
Addr g;
|
||||
|
||||
g = nullgen;
|
||||
g.Type = obj.TYPE_CONST;
|
||||
g.Offset = int64($6);
|
||||
outcode($1, $2, &$3, 0, &g);
|
||||
g.type = D_CONST;
|
||||
g.offset = $6;
|
||||
outcode($1, $2, &$3, NREG, &g);
|
||||
}
|
||||
| LTYPE8 cond '[' reglist ']' ',' ioreg
|
||||
{
|
||||
var g obj.Addr
|
||||
Addr g;
|
||||
|
||||
g = nullgen;
|
||||
g.Type = obj.TYPE_CONST;
|
||||
g.Offset = int64($4);
|
||||
outcode($1, $2, &g, 0, &$7);
|
||||
g.type = D_CONST;
|
||||
g.offset = $4;
|
||||
outcode($1, $2, &g, NREG, &$7);
|
||||
}
|
||||
/*
|
||||
* SWAP
|
||||
*/
|
||||
| LTYPE9 cond reg ',' ireg ',' reg
|
||||
{
|
||||
outcode($1, $2, &$5, int32($3.Reg), &$7);
|
||||
outcode($1, $2, &$5, $3.reg, &$7);
|
||||
}
|
||||
| LTYPE9 cond reg ',' ireg comma
|
||||
{
|
||||
outcode($1, $2, &$5, int32($3.Reg), &$3);
|
||||
outcode($1, $2, &$5, $3.reg, &$3);
|
||||
}
|
||||
| LTYPE9 cond comma ireg ',' reg
|
||||
{
|
||||
outcode($1, $2, &$4, int32($6.Reg), &$6);
|
||||
outcode($1, $2, &$4, $6.reg, &$6);
|
||||
}
|
||||
/*
|
||||
* RET
|
||||
*/
|
||||
| LTYPEA cond comma
|
||||
{
|
||||
outcode($1, $2, &nullgen, 0, &nullgen);
|
||||
outcode($1, $2, &nullgen, NREG, &nullgen);
|
||||
}
|
||||
/*
|
||||
* TEXT
|
||||
* TEXT/GLOBL
|
||||
*/
|
||||
| LTYPEB name ',' '$' textsize
|
||||
| LTYPEB name ',' imm
|
||||
{
|
||||
asm.Settext($2.Sym);
|
||||
outcode($1, Always, &$2, 0, &$5);
|
||||
$4.type = D_CONST2;
|
||||
$4.offset2 = ArgsSizeUnknown;
|
||||
outcode($1, Always, &$2, 0, &$4);
|
||||
}
|
||||
| LTYPEB name ',' con ',' '$' textsize
|
||||
| LTYPEB name ',' con ',' imm
|
||||
{
|
||||
asm.Settext($2.Sym);
|
||||
outcode($1, Always, &$2, 0, &$7);
|
||||
if asm.Pass > 1 {
|
||||
lastpc.From3.Type = obj.TYPE_CONST;
|
||||
lastpc.From3.Offset = int64($4)
|
||||
}
|
||||
$6.type = D_CONST2;
|
||||
$6.offset2 = ArgsSizeUnknown;
|
||||
outcode($1, Always, &$2, $4, &$6);
|
||||
}
|
||||
/*
|
||||
* GLOBL
|
||||
*/
|
||||
| LGLOBL name ',' imm
|
||||
| LTYPEB name ',' con ',' imm '-' con
|
||||
{
|
||||
asm.Settext($2.Sym)
|
||||
outcode($1, Always, &$2, 0, &$4)
|
||||
$6.type = D_CONST2;
|
||||
$6.offset2 = $8;
|
||||
outcode($1, Always, &$2, $4, &$6);
|
||||
}
|
||||
| LGLOBL name ',' con ',' imm
|
||||
{
|
||||
asm.Settext($2.Sym)
|
||||
outcode($1, Always, &$2, 0, &$6)
|
||||
if asm.Pass > 1 {
|
||||
lastpc.From3.Type = obj.TYPE_CONST
|
||||
lastpc.From3.Offset = int64($4)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* DATA
|
||||
*/
|
||||
| LTYPEC name '/' con ',' ximm
|
||||
{
|
||||
outcode($1, Always, &$2, 0, &$6)
|
||||
if asm.Pass > 1 {
|
||||
lastpc.From3.Type = obj.TYPE_CONST
|
||||
lastpc.From3.Offset = int64($4)
|
||||
}
|
||||
outcode($1, Always, &$2, $4, &$6);
|
||||
}
|
||||
/*
|
||||
* CASE
|
||||
*/
|
||||
| LTYPED cond reg comma
|
||||
{
|
||||
outcode($1, $2, &$3, 0, &nullgen);
|
||||
outcode($1, $2, &$3, NREG, &nullgen);
|
||||
}
|
||||
/*
|
||||
* word
|
||||
*/
|
||||
| LTYPEH comma ximm
|
||||
{
|
||||
outcode($1, Always, &nullgen, 0, &$3);
|
||||
outcode($1, Always, &nullgen, NREG, &$3);
|
||||
}
|
||||
/*
|
||||
* floating-point coprocessor
|
||||
*/
|
||||
| LTYPEI cond freg ',' freg
|
||||
{
|
||||
outcode($1, $2, &$3, 0, &$5);
|
||||
outcode($1, $2, &$3, NREG, &$5);
|
||||
}
|
||||
| LTYPEK cond frcon ',' freg
|
||||
{
|
||||
outcode($1, $2, &$3, 0, &$5);
|
||||
outcode($1, $2, &$3, NREG, &$5);
|
||||
}
|
||||
| LTYPEK cond frcon ',' LFREG ',' freg
|
||||
{
|
||||
@@ -291,113 +272,80 @@ inst:
|
||||
}
|
||||
| LTYPEL cond freg ',' freg comma
|
||||
{
|
||||
outcode($1, $2, &$3, int32($5.Reg), &nullgen);
|
||||
outcode($1, $2, &$3, $5.reg, &nullgen);
|
||||
}
|
||||
/*
|
||||
* MCR MRC
|
||||
*/
|
||||
| LTYPEJ cond con ',' expr ',' spreg ',' creg ',' creg oexpr
|
||||
{
|
||||
var g obj.Addr
|
||||
Addr g;
|
||||
|
||||
g = nullgen;
|
||||
g.Type = obj.TYPE_CONST;
|
||||
g.Offset = int64(
|
||||
g.type = D_CONST;
|
||||
g.offset =
|
||||
(0xe << 24) | /* opcode */
|
||||
($1 << 20) | /* MCR/MRC */
|
||||
(($2^C_SCOND_XOR) << 28) | /* scond */
|
||||
($2 << 28) | /* scond */
|
||||
(($3 & 15) << 8) | /* coprocessor number */
|
||||
(($5 & 7) << 21) | /* coprocessor operation */
|
||||
(($7 & 15) << 12) | /* arm register */
|
||||
(($9 & 15) << 16) | /* Crn */
|
||||
(($11 & 15) << 0) | /* Crm */
|
||||
(($12 & 7) << 5) | /* coprocessor information */
|
||||
(1<<4)); /* must be set */
|
||||
outcode(AMRC, Always, &nullgen, 0, &g);
|
||||
(1<<4); /* must be set */
|
||||
outcode(AMRC, Always, &nullgen, NREG, &g);
|
||||
}
|
||||
/*
|
||||
* MULL r1,r2,(hi,lo)
|
||||
*/
|
||||
| LTYPEM cond reg ',' reg ',' regreg
|
||||
{
|
||||
outcode($1, $2, &$3, int32($5.Reg), &$7);
|
||||
outcode($1, $2, &$3, $5.reg, &$7);
|
||||
}
|
||||
/*
|
||||
* MULA r1,r2,r3,r4: (r1*r2+r3) & 0xffffffff . r4
|
||||
* MULA r1,r2,r3,r4: (r1*r2+r3) & 0xffffffff -> r4
|
||||
* MULAW{T,B} r1,r2,r3,r4
|
||||
*/
|
||||
| LTYPEN cond reg ',' reg ',' reg ',' spreg
|
||||
{
|
||||
$7.Type = obj.TYPE_REGREG2;
|
||||
$7.Offset = int64($9);
|
||||
outcode($1, $2, &$3, int32($5.Reg), &$7);
|
||||
$7.type = D_REGREG2;
|
||||
$7.offset = $9;
|
||||
outcode($1, $2, &$3, $5.reg, &$7);
|
||||
}
|
||||
/*
|
||||
* PLD
|
||||
*/
|
||||
| LTYPEPLD oreg
|
||||
{
|
||||
outcode($1, Always, &$2, 0, &nullgen);
|
||||
outcode($1, Always, &$2, NREG, &nullgen);
|
||||
}
|
||||
/*
|
||||
* PCDATA
|
||||
*/
|
||||
| LTYPEPC gen ',' gen
|
||||
{
|
||||
if $2.Type != obj.TYPE_CONST || $4.Type != obj.TYPE_CONST {
|
||||
yyerror("arguments to PCDATA must be integer constants")
|
||||
}
|
||||
outcode($1, Always, &$2, 0, &$4);
|
||||
if($2.type != D_CONST || $4.type != D_CONST)
|
||||
yyerror("arguments to PCDATA must be integer constants");
|
||||
outcode($1, Always, &$2, NREG, &$4);
|
||||
}
|
||||
/*
|
||||
* FUNCDATA
|
||||
*/
|
||||
| LTYPEF gen ',' gen
|
||||
{
|
||||
if $2.Type != obj.TYPE_CONST {
|
||||
yyerror("index for FUNCDATA must be integer constant")
|
||||
}
|
||||
if $4.Type != obj.NAME_EXTERN && $4.Type != obj.NAME_STATIC && $4.Type != obj.TYPE_MEM {
|
||||
yyerror("value for FUNCDATA must be symbol reference")
|
||||
}
|
||||
outcode($1, Always, &$2, 0, &$4);
|
||||
if($2.type != D_CONST)
|
||||
yyerror("index for FUNCDATA must be integer constant");
|
||||
if($4.type != D_EXTERN && $4.type != D_STATIC && $4.type != D_OREG)
|
||||
yyerror("value for FUNCDATA must be symbol reference");
|
||||
outcode($1, Always, &$2, NREG, &$4);
|
||||
}
|
||||
/*
|
||||
* END
|
||||
*/
|
||||
| LTYPEE comma
|
||||
{
|
||||
outcode($1, Always, &nullgen, 0, &nullgen);
|
||||
}
|
||||
|
||||
textsize:
|
||||
LCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_TEXTSIZE;
|
||||
$$.Offset = int64($1)
|
||||
$$.U.Argsize = obj.ArgsSizeUnknown;
|
||||
}
|
||||
| '-' LCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_TEXTSIZE;
|
||||
$$.Offset = -int64($2)
|
||||
$$.U.Argsize = obj.ArgsSizeUnknown;
|
||||
}
|
||||
| LCONST '-' LCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_TEXTSIZE;
|
||||
$$.Offset = int64($1)
|
||||
$$.U.Argsize = int32($3);
|
||||
}
|
||||
| '-' LCONST '-' LCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_TEXTSIZE;
|
||||
$$.Offset = -int64($2)
|
||||
$$.U.Argsize = int32($4);
|
||||
outcode($1, Always, &nullgen, NREG, &nullgen);
|
||||
}
|
||||
|
||||
cond:
|
||||
@@ -406,7 +354,7 @@ cond:
|
||||
}
|
||||
| cond LCOND
|
||||
{
|
||||
$$ = ($1 & ^ C_SCOND) | $2;
|
||||
$$ = ($1 & ~C_SCOND) | $2;
|
||||
}
|
||||
| cond LS
|
||||
{
|
||||
@@ -420,36 +368,45 @@ rel:
|
||||
con '(' LPC ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_BRANCH;
|
||||
$$.Offset = int64($1) + int64(asm.PC);
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $1 + pc;
|
||||
}
|
||||
| LNAME offset
|
||||
{
|
||||
$1 = asm.LabelLookup($1);
|
||||
$$ = nullgen;
|
||||
if asm.Pass == 2 && $1.Type != LLAB {
|
||||
yyerror("undefined label: %s", $1.Labelname)
|
||||
}
|
||||
$$.Type = obj.TYPE_BRANCH;
|
||||
$$.Offset = $1.Value + int64($2);
|
||||
if(pass == 2)
|
||||
yyerror("undefined label: %s", $1->name);
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $2;
|
||||
}
|
||||
| LLAB offset
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $1->value + $2;
|
||||
}
|
||||
|
||||
ximm: '$' con
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_CONST;
|
||||
$$.Offset = int64($2);
|
||||
$$.type = D_CONST;
|
||||
$$.offset = $2;
|
||||
}
|
||||
| '$' oreg
|
||||
{
|
||||
$$ = $2;
|
||||
$$.Type = obj.TYPE_ADDR;
|
||||
$$.type = D_CONST;
|
||||
}
|
||||
| '$' '*' '$' oreg
|
||||
{
|
||||
$$ = $4;
|
||||
$$.type = D_OCONST;
|
||||
}
|
||||
| '$' LSCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_SCONST;
|
||||
$$.U.Sval = $2
|
||||
$$.type = D_SCONST;
|
||||
memcpy($$.u.sval, $2, sizeof($$.u.sval));
|
||||
}
|
||||
| fcon
|
||||
|
||||
@@ -457,34 +414,33 @@ fcon:
|
||||
'$' LFCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_FCONST;
|
||||
$$.U.Dval = $2;
|
||||
$$.type = D_FCONST;
|
||||
$$.u.dval = $2;
|
||||
}
|
||||
| '$' '-' LFCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_FCONST;
|
||||
$$.U.Dval = -$3;
|
||||
$$.type = D_FCONST;
|
||||
$$.u.dval = -$3;
|
||||
}
|
||||
|
||||
reglist:
|
||||
spreg
|
||||
{
|
||||
$$ = 1 << uint($1&15);
|
||||
$$ = 1 << $1;
|
||||
}
|
||||
| spreg '-' spreg
|
||||
{
|
||||
int i;
|
||||
$$=0;
|
||||
for i:=$1; i<=$3; i++ {
|
||||
$$ |= 1<<uint(i&15)
|
||||
}
|
||||
for i:=$3; i<=$1; i++ {
|
||||
$$ |= 1<<uint(i&15)
|
||||
}
|
||||
for(i=$1; i<=$3; i++)
|
||||
$$ |= 1<<i;
|
||||
for(i=$3; i<=$1; i++)
|
||||
$$ |= 1<<i;
|
||||
}
|
||||
| spreg comma reglist
|
||||
{
|
||||
$$ = (1<<uint($1&15)) | $3;
|
||||
$$ = (1<<$1) | $3;
|
||||
}
|
||||
|
||||
gen:
|
||||
@@ -494,25 +450,25 @@ gen:
|
||||
| shift '(' spreg ')'
|
||||
{
|
||||
$$ = $1;
|
||||
$$.Reg = int16($3);
|
||||
$$.reg = $3;
|
||||
}
|
||||
| LPSR
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_REG
|
||||
$$.Reg = int16($1);
|
||||
$$.type = D_PSR;
|
||||
$$.reg = $1;
|
||||
}
|
||||
| LFCR
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_REG
|
||||
$$.Reg = int16($1);
|
||||
$$.type = D_FPCR;
|
||||
$$.reg = $1;
|
||||
}
|
||||
| con
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_MEM;
|
||||
$$.Offset = int64($1);
|
||||
$$.type = D_OREG;
|
||||
$$.offset = $1;
|
||||
}
|
||||
| oreg
|
||||
| freg
|
||||
@@ -522,7 +478,7 @@ nireg:
|
||||
| name
|
||||
{
|
||||
$$ = $1;
|
||||
if($1.Name != obj.NAME_EXTERN && $1.Name != obj.NAME_STATIC) {
|
||||
if($1.name != D_EXTERN && $1.name != D_STATIC) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -530,9 +486,9 @@ ireg:
|
||||
'(' spreg ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_MEM;
|
||||
$$.Reg = int16($2);
|
||||
$$.Offset = 0;
|
||||
$$.type = D_OREG;
|
||||
$$.reg = $2;
|
||||
$$.offset = 0;
|
||||
}
|
||||
|
||||
ioreg:
|
||||
@@ -540,9 +496,9 @@ ioreg:
|
||||
| con '(' sreg ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_MEM;
|
||||
$$.Reg = int16($3);
|
||||
$$.Offset = int64($1);
|
||||
$$.type = D_OREG;
|
||||
$$.reg = $3;
|
||||
$$.offset = $1;
|
||||
}
|
||||
|
||||
oreg:
|
||||
@@ -550,8 +506,8 @@ oreg:
|
||||
| name '(' sreg ')'
|
||||
{
|
||||
$$ = $1;
|
||||
$$.Type = obj.TYPE_MEM;
|
||||
$$.Reg = int16($3);
|
||||
$$.type = D_OREG;
|
||||
$$.reg = $3;
|
||||
}
|
||||
| ioreg
|
||||
|
||||
@@ -563,66 +519,64 @@ imsr:
|
||||
imm: '$' con
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_CONST;
|
||||
$$.Offset = int64($2);
|
||||
$$.type = D_CONST;
|
||||
$$.offset = $2;
|
||||
}
|
||||
|
||||
reg:
|
||||
spreg
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_REG;
|
||||
$$.Reg = int16($1);
|
||||
$$.type = D_REG;
|
||||
$$.reg = $1;
|
||||
}
|
||||
|
||||
regreg:
|
||||
'(' spreg ',' spreg ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_REGREG;
|
||||
$$.Reg = int16($2);
|
||||
$$.Offset = int64($4);
|
||||
$$.type = D_REGREG;
|
||||
$$.reg = $2;
|
||||
$$.offset = $4;
|
||||
}
|
||||
|
||||
shift:
|
||||
spreg '<' '<' rcon
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_SHIFT;
|
||||
$$.Offset = int64($1&15) | int64($4) | (0 << 5);
|
||||
$$.type = D_SHIFT;
|
||||
$$.offset = $1 | $4 | (0 << 5);
|
||||
}
|
||||
| spreg '>' '>' rcon
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_SHIFT;
|
||||
$$.Offset = int64($1&15) | int64($4) | (1 << 5);
|
||||
$$.type = D_SHIFT;
|
||||
$$.offset = $1 | $4 | (1 << 5);
|
||||
}
|
||||
| spreg '-' '>' rcon
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_SHIFT;
|
||||
$$.Offset = int64($1&15) | int64($4) | (2 << 5);
|
||||
$$.type = D_SHIFT;
|
||||
$$.offset = $1 | $4 | (2 << 5);
|
||||
}
|
||||
| spreg LAT '>' rcon
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_SHIFT;
|
||||
$$.Offset = int64($1&15) | int64($4) | (3 << 5);
|
||||
$$.type = D_SHIFT;
|
||||
$$.offset = $1 | $4 | (3 << 5);
|
||||
}
|
||||
|
||||
rcon:
|
||||
spreg
|
||||
{
|
||||
if $$ < REG_R0 || $$ > REG_R15 {
|
||||
print("register value out of range\n")
|
||||
}
|
||||
if($$ < 0 || $$ >= 16)
|
||||
print("register value out of range\n");
|
||||
$$ = (($1&15) << 8) | (1 << 4);
|
||||
}
|
||||
| con
|
||||
{
|
||||
if $$ < 0 || $$ >= 32 {
|
||||
print("shift value out of range\n")
|
||||
}
|
||||
if($$ < 0 || $$ >= 32)
|
||||
print("shift value out of range\n");
|
||||
$$ = ($1&31) << 7;
|
||||
}
|
||||
|
||||
@@ -634,10 +588,9 @@ sreg:
|
||||
}
|
||||
| LR '(' expr ')'
|
||||
{
|
||||
if $3 < 0 || $3 >= NREG {
|
||||
print("register value out of range\n")
|
||||
}
|
||||
$$ = REG_R0 + $3;
|
||||
if($3 < 0 || $3 >= NREG)
|
||||
print("register value out of range\n");
|
||||
$$ = $3;
|
||||
}
|
||||
|
||||
spreg:
|
||||
@@ -651,10 +604,9 @@ creg:
|
||||
LCREG
|
||||
| LC '(' expr ')'
|
||||
{
|
||||
if $3 < 0 || $3 >= NREG {
|
||||
print("register value out of range\n")
|
||||
}
|
||||
$$ = $3; // TODO(rsc): REG_C0+$3
|
||||
if($3 < 0 || $3 >= NREG)
|
||||
print("register value out of range\n");
|
||||
$$ = $3;
|
||||
}
|
||||
|
||||
frcon:
|
||||
@@ -665,40 +617,40 @@ freg:
|
||||
LFREG
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_REG;
|
||||
$$.Reg = int16($1);
|
||||
$$.type = D_FREG;
|
||||
$$.reg = $1;
|
||||
}
|
||||
| LF '(' con ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_REG;
|
||||
$$.Reg = int16(REG_F0 + $3);
|
||||
$$.type = D_FREG;
|
||||
$$.reg = $3;
|
||||
}
|
||||
|
||||
name:
|
||||
con '(' pointer ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_MEM;
|
||||
$$.Name = int8($3);
|
||||
$$.Sym = nil;
|
||||
$$.Offset = int64($1);
|
||||
$$.type = D_OREG;
|
||||
$$.name = $3;
|
||||
$$.sym = nil;
|
||||
$$.offset = $1;
|
||||
}
|
||||
| LNAME offset '(' pointer ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_MEM;
|
||||
$$.Name = int8($4);
|
||||
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 0);
|
||||
$$.Offset = int64($2);
|
||||
$$.type = D_OREG;
|
||||
$$.name = $4;
|
||||
$$.sym = linklookup(ctxt, $1->name, 0);
|
||||
$$.offset = $2;
|
||||
}
|
||||
| LNAME '<' '>' offset '(' LSB ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.Type = obj.TYPE_MEM;
|
||||
$$.Name = obj.NAME_STATIC;
|
||||
$$.Sym = obj.Linklookup(asm.Ctxt, $1.Name, 1);
|
||||
$$.Offset = int64($4);
|
||||
$$.type = D_OREG;
|
||||
$$.name = D_STATIC;
|
||||
$$.sym = linklookup(ctxt, $1->name, 1);
|
||||
$$.offset = $4;
|
||||
}
|
||||
|
||||
offset:
|
||||
@@ -723,7 +675,7 @@ con:
|
||||
LCONST
|
||||
| LVAR
|
||||
{
|
||||
$$ = int32($1.Value);
|
||||
$$ = $1->value;
|
||||
}
|
||||
| '-' con
|
||||
{
|
||||
@@ -735,7 +687,7 @@ con:
|
||||
}
|
||||
| '~' con
|
||||
{
|
||||
$$ = ^$2;
|
||||
$$ = ~$2;
|
||||
}
|
||||
| '(' expr ')'
|
||||
{
|
||||
@@ -775,11 +727,11 @@ expr:
|
||||
}
|
||||
| expr '<' '<' expr
|
||||
{
|
||||
$$ = $1 << uint($4);
|
||||
$$ = $1 << $4;
|
||||
}
|
||||
| expr '>' '>' expr
|
||||
{
|
||||
$$ = $1 >> uint($4);
|
||||
$$ = $1 >> $4;
|
||||
}
|
||||
| expr '&' expr
|
||||
{
|
||||
|
||||
20
src/cmd/5a/doc.go
Normal file
20
src/cmd/5a/doc.go
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build ignore
|
||||
|
||||
/*
|
||||
|
||||
5a is a version of the Plan 9 assembler. The original is documented at
|
||||
|
||||
http://plan9.bell-labs.com/magic/man2html/1/8a
|
||||
|
||||
Go-specific considerations are documented at
|
||||
|
||||
http://golang.org/doc/asm
|
||||
|
||||
Its target architecture is the ARM, referred to by these tools as arm.
|
||||
|
||||
*/
|
||||
package main
|
||||
538
src/cmd/5a/lex.c
Normal file
538
src/cmd/5a/lex.c
Normal file
@@ -0,0 +1,538 @@
|
||||
// Inferno utils/5a/lex.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/5a/lex.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#define EXTERN
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "a.h"
|
||||
#include "y.tab.h"
|
||||
|
||||
enum
|
||||
{
|
||||
Plan9 = 1<<0,
|
||||
Unix = 1<<1,
|
||||
Windows = 1<<2,
|
||||
};
|
||||
|
||||
int
|
||||
systemtype(int sys)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return sys&Windows;
|
||||
#else
|
||||
return sys&Plan9;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
Lconv(Fmt *fp)
|
||||
{
|
||||
return linklinefmt(ctxt, fp);
|
||||
}
|
||||
|
||||
void
|
||||
dodef(char *p)
|
||||
{
|
||||
if(nDlist%8 == 0)
|
||||
Dlist = allocn(Dlist, nDlist*sizeof(char *),
|
||||
8*sizeof(char *));
|
||||
Dlist[nDlist++] = p;
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
print("usage: %ca [options] file.c...\n", thechar);
|
||||
flagprint(1);
|
||||
errorexit();
|
||||
}
|
||||
|
||||
void
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *p;
|
||||
|
||||
thechar = '5';
|
||||
thestring = "arm";
|
||||
|
||||
ctxt = linknew(&linkarm);
|
||||
ctxt->diag = yyerror;
|
||||
ctxt->bso = &bstdout;
|
||||
ctxt->enforce_data_order = 1;
|
||||
Binit(&bstdout, 1, OWRITE);
|
||||
listinit5();
|
||||
fmtinstall('L', Lconv);
|
||||
|
||||
// Allow GOARCH=thestring or GOARCH=thestringsuffix,
|
||||
// but not other values.
|
||||
p = getgoarch();
|
||||
if(strncmp(p, thestring, strlen(thestring)) != 0)
|
||||
sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
|
||||
|
||||
ensuresymb(NSYMB);
|
||||
memset(debug, 0, sizeof(debug));
|
||||
cinit();
|
||||
outfile = 0;
|
||||
setinclude(".");
|
||||
|
||||
flagfn1("D", "name[=value]: add #define", dodef);
|
||||
flagfn1("I", "dir: add dir to include path", setinclude);
|
||||
flagcount("S", "print assembly and machine code", &debug['S']);
|
||||
flagcount("m", "debug preprocessor macros", &debug['m']);
|
||||
flagstr("o", "file: set output file", &outfile);
|
||||
flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
|
||||
|
||||
flagparse(&argc, &argv, usage);
|
||||
ctxt->debugasm = debug['S'];
|
||||
|
||||
if(argc < 1)
|
||||
usage();
|
||||
if(argc > 1){
|
||||
print("can't assemble multiple files\n");
|
||||
errorexit();
|
||||
}
|
||||
|
||||
if(assemble(argv[0]))
|
||||
errorexit();
|
||||
Bflush(&bstdout);
|
||||
exits(0);
|
||||
}
|
||||
|
||||
int
|
||||
assemble(char *file)
|
||||
{
|
||||
char *ofile, *p;
|
||||
int i, of;
|
||||
|
||||
ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar)
|
||||
strcpy(ofile, file);
|
||||
p = utfrrune(ofile, '/');
|
||||
if(p) {
|
||||
include[0] = ofile;
|
||||
*p++ = 0;
|
||||
} else
|
||||
p = ofile;
|
||||
if(outfile == 0) {
|
||||
outfile = p;
|
||||
if(outfile){
|
||||
p = utfrrune(outfile, '.');
|
||||
if(p)
|
||||
if(p[1] == 's' && p[2] == 0)
|
||||
p[0] = 0;
|
||||
p = utfrune(outfile, 0);
|
||||
p[0] = '.';
|
||||
p[1] = thechar;
|
||||
p[2] = 0;
|
||||
} else
|
||||
outfile = "/dev/null";
|
||||
}
|
||||
|
||||
of = create(outfile, OWRITE, 0664);
|
||||
if(of < 0) {
|
||||
yyerror("%ca: cannot create %s", thechar, outfile);
|
||||
errorexit();
|
||||
}
|
||||
Binit(&obuf, of, OWRITE);
|
||||
Bprint(&obuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
|
||||
Bprint(&obuf, "!\n");
|
||||
|
||||
for(pass = 1; pass <= 2; pass++) {
|
||||
pinit(file);
|
||||
for(i=0; i<nDlist; i++)
|
||||
dodefine(Dlist[i]);
|
||||
yyparse();
|
||||
cclean();
|
||||
if(nerrors)
|
||||
return nerrors;
|
||||
}
|
||||
|
||||
writeobj(ctxt, &obuf);
|
||||
Bflush(&obuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct
|
||||
{
|
||||
char *name;
|
||||
ushort type;
|
||||
ushort value;
|
||||
} itab[] =
|
||||
{
|
||||
"SP", LSP, D_AUTO,
|
||||
"SB", LSB, D_EXTERN,
|
||||
"FP", LFP, D_PARAM,
|
||||
"PC", LPC, D_BRANCH,
|
||||
|
||||
"R", LR, 0,
|
||||
"R0", LREG, 0,
|
||||
"R1", LREG, 1,
|
||||
"R2", LREG, 2,
|
||||
"R3", LREG, 3,
|
||||
"R4", LREG, 4,
|
||||
"R5", LREG, 5,
|
||||
"R6", LREG, 6,
|
||||
"R7", LREG, 7,
|
||||
"R8", LREG, 8,
|
||||
"R9", LREG, 9,
|
||||
"g", LREG, 10, // avoid unintentionally clobber g using R10
|
||||
"R11", LREG, 11,
|
||||
"R12", LREG, 12,
|
||||
"R13", LREG, 13,
|
||||
"R14", LREG, 14,
|
||||
"R15", LREG, 15,
|
||||
|
||||
"F", LF, 0,
|
||||
|
||||
"F0", LFREG, 0,
|
||||
"F1", LFREG, 1,
|
||||
"F2", LFREG, 2,
|
||||
"F3", LFREG, 3,
|
||||
"F4", LFREG, 4,
|
||||
"F5", LFREG, 5,
|
||||
"F6", LFREG, 6,
|
||||
"F7", LFREG, 7,
|
||||
"F8", LFREG, 8,
|
||||
"F9", LFREG, 9,
|
||||
"F10", LFREG, 10,
|
||||
"F11", LFREG, 11,
|
||||
"F12", LFREG, 12,
|
||||
"F13", LFREG, 13,
|
||||
"F14", LFREG, 14,
|
||||
"F15", LFREG, 15,
|
||||
|
||||
"C", LC, 0,
|
||||
|
||||
"C0", LCREG, 0,
|
||||
"C1", LCREG, 1,
|
||||
"C2", LCREG, 2,
|
||||
"C3", LCREG, 3,
|
||||
"C4", LCREG, 4,
|
||||
"C5", LCREG, 5,
|
||||
"C6", LCREG, 6,
|
||||
"C7", LCREG, 7,
|
||||
"C8", LCREG, 8,
|
||||
"C9", LCREG, 9,
|
||||
"C10", LCREG, 10,
|
||||
"C11", LCREG, 11,
|
||||
"C12", LCREG, 12,
|
||||
"C13", LCREG, 13,
|
||||
"C14", LCREG, 14,
|
||||
"C15", LCREG, 15,
|
||||
|
||||
"CPSR", LPSR, 0,
|
||||
"SPSR", LPSR, 1,
|
||||
|
||||
"FPSR", LFCR, 0,
|
||||
"FPCR", LFCR, 1,
|
||||
|
||||
".EQ", LCOND, 0,
|
||||
".NE", LCOND, 1,
|
||||
".CS", LCOND, 2,
|
||||
".HS", LCOND, 2,
|
||||
".CC", LCOND, 3,
|
||||
".LO", LCOND, 3,
|
||||
".MI", LCOND, 4,
|
||||
".PL", LCOND, 5,
|
||||
".VS", LCOND, 6,
|
||||
".VC", LCOND, 7,
|
||||
".HI", LCOND, 8,
|
||||
".LS", LCOND, 9,
|
||||
".GE", LCOND, 10,
|
||||
".LT", LCOND, 11,
|
||||
".GT", LCOND, 12,
|
||||
".LE", LCOND, 13,
|
||||
".AL", LCOND, Always,
|
||||
|
||||
".U", LS, C_UBIT,
|
||||
".S", LS, C_SBIT,
|
||||
".W", LS, C_WBIT,
|
||||
".P", LS, C_PBIT,
|
||||
".PW", LS, C_WBIT|C_PBIT,
|
||||
".WP", LS, C_WBIT|C_PBIT,
|
||||
|
||||
".F", LS, C_FBIT,
|
||||
|
||||
".IBW", LS, C_WBIT|C_PBIT|C_UBIT,
|
||||
".IAW", LS, C_WBIT|C_UBIT,
|
||||
".DBW", LS, C_WBIT|C_PBIT,
|
||||
".DAW", LS, C_WBIT,
|
||||
".IB", LS, C_PBIT|C_UBIT,
|
||||
".IA", LS, C_UBIT,
|
||||
".DB", LS, C_PBIT,
|
||||
".DA", LS, 0,
|
||||
|
||||
"@", LAT, 0,
|
||||
|
||||
"AND", LTYPE1, AAND,
|
||||
"EOR", LTYPE1, AEOR,
|
||||
"SUB", LTYPE1, ASUB,
|
||||
"RSB", LTYPE1, ARSB,
|
||||
"ADD", LTYPE1, AADD,
|
||||
"ADC", LTYPE1, AADC,
|
||||
"SBC", LTYPE1, ASBC,
|
||||
"RSC", LTYPE1, ARSC,
|
||||
"ORR", LTYPE1, AORR,
|
||||
"BIC", LTYPE1, ABIC,
|
||||
|
||||
"SLL", LTYPE1, ASLL,
|
||||
"SRL", LTYPE1, ASRL,
|
||||
"SRA", LTYPE1, ASRA,
|
||||
|
||||
"MUL", LTYPE1, AMUL,
|
||||
"MULA", LTYPEN, AMULA,
|
||||
"DIV", LTYPE1, ADIV,
|
||||
"MOD", LTYPE1, AMOD,
|
||||
|
||||
"MULL", LTYPEM, AMULL,
|
||||
"MULAL", LTYPEM, AMULAL,
|
||||
"MULLU", LTYPEM, AMULLU,
|
||||
"MULALU", LTYPEM, AMULALU,
|
||||
|
||||
"MVN", LTYPE2, AMVN, /* op2 ignored */
|
||||
|
||||
"MOVB", LTYPE3, AMOVB,
|
||||
"MOVBU", LTYPE3, AMOVBU,
|
||||
"MOVH", LTYPE3, AMOVH,
|
||||
"MOVHU", LTYPE3, AMOVHU,
|
||||
"MOVW", LTYPE3, AMOVW,
|
||||
|
||||
"MOVD", LTYPE3, AMOVD,
|
||||
"MOVDF", LTYPE3, AMOVDF,
|
||||
"MOVDW", LTYPE3, AMOVDW,
|
||||
"MOVF", LTYPE3, AMOVF,
|
||||
"MOVFD", LTYPE3, AMOVFD,
|
||||
"MOVFW", LTYPE3, AMOVFW,
|
||||
"MOVWD", LTYPE3, AMOVWD,
|
||||
"MOVWF", LTYPE3, AMOVWF,
|
||||
|
||||
"LDREX", LTYPE3, ALDREX,
|
||||
"LDREXD", LTYPE3, ALDREXD,
|
||||
"STREX", LTYPE9, ASTREX,
|
||||
"STREXD", LTYPE9, ASTREXD,
|
||||
|
||||
/*
|
||||
"NEGF", LTYPEI, ANEGF,
|
||||
"NEGD", LTYPEI, ANEGD,
|
||||
"SQTF", LTYPEI, ASQTF,
|
||||
"SQTD", LTYPEI, ASQTD,
|
||||
"RNDF", LTYPEI, ARNDF,
|
||||
"RNDD", LTYPEI, ARNDD,
|
||||
"URDF", LTYPEI, AURDF,
|
||||
"URDD", LTYPEI, AURDD,
|
||||
"NRMF", LTYPEI, ANRMF,
|
||||
"NRMD", LTYPEI, ANRMD,
|
||||
*/
|
||||
|
||||
"ABSF", LTYPEI, AABSF,
|
||||
"ABSD", LTYPEI, AABSD,
|
||||
"SQRTF", LTYPEI, ASQRTF,
|
||||
"SQRTD", LTYPEI, ASQRTD,
|
||||
"CMPF", LTYPEL, ACMPF,
|
||||
"CMPD", LTYPEL, ACMPD,
|
||||
"ADDF", LTYPEK, AADDF,
|
||||
"ADDD", LTYPEK, AADDD,
|
||||
"SUBF", LTYPEK, ASUBF,
|
||||
"SUBD", LTYPEK, ASUBD,
|
||||
"MULF", LTYPEK, AMULF,
|
||||
"MULD", LTYPEK, AMULD,
|
||||
"DIVF", LTYPEK, ADIVF,
|
||||
"DIVD", LTYPEK, ADIVD,
|
||||
|
||||
"B", LTYPE4, AB,
|
||||
"BL", LTYPE4, ABL,
|
||||
"BX", LTYPEBX, ABX,
|
||||
|
||||
"BEQ", LTYPE5, ABEQ,
|
||||
"BNE", LTYPE5, ABNE,
|
||||
"BCS", LTYPE5, ABCS,
|
||||
"BHS", LTYPE5, ABHS,
|
||||
"BCC", LTYPE5, ABCC,
|
||||
"BLO", LTYPE5, ABLO,
|
||||
"BMI", LTYPE5, ABMI,
|
||||
"BPL", LTYPE5, ABPL,
|
||||
"BVS", LTYPE5, ABVS,
|
||||
"BVC", LTYPE5, ABVC,
|
||||
"BHI", LTYPE5, ABHI,
|
||||
"BLS", LTYPE5, ABLS,
|
||||
"BGE", LTYPE5, ABGE,
|
||||
"BLT", LTYPE5, ABLT,
|
||||
"BGT", LTYPE5, ABGT,
|
||||
"BLE", LTYPE5, ABLE,
|
||||
"BCASE", LTYPE5, ABCASE,
|
||||
|
||||
"SWI", LTYPE6, ASWI,
|
||||
|
||||
"CMP", LTYPE7, ACMP,
|
||||
"TST", LTYPE7, ATST,
|
||||
"TEQ", LTYPE7, ATEQ,
|
||||
"CMN", LTYPE7, ACMN,
|
||||
|
||||
"MOVM", LTYPE8, AMOVM,
|
||||
|
||||
"SWPBU", LTYPE9, ASWPBU,
|
||||
"SWPW", LTYPE9, ASWPW,
|
||||
|
||||
"RET", LTYPEA, ARET,
|
||||
"RFE", LTYPEA, ARFE,
|
||||
|
||||
"TEXT", LTYPEB, ATEXT,
|
||||
"GLOBL", LTYPEB, AGLOBL,
|
||||
"DATA", LTYPEC, ADATA,
|
||||
"CASE", LTYPED, ACASE,
|
||||
"END", LTYPEE, AEND,
|
||||
"WORD", LTYPEH, AWORD,
|
||||
"NOP", LTYPEI, ANOP,
|
||||
|
||||
"MCR", LTYPEJ, 0,
|
||||
"MRC", LTYPEJ, 1,
|
||||
|
||||
"PLD", LTYPEPLD, APLD,
|
||||
"UNDEF", LTYPEE, AUNDEF,
|
||||
"CLZ", LTYPE2, ACLZ,
|
||||
|
||||
"MULWT", LTYPE1, AMULWT,
|
||||
"MULWB", LTYPE1, AMULWB,
|
||||
"MULAWT", LTYPEN, AMULAWT,
|
||||
"MULAWB", LTYPEN, AMULAWB,
|
||||
|
||||
"USEFIELD", LTYPEN, AUSEFIELD,
|
||||
"PCDATA", LTYPEPC, APCDATA,
|
||||
"FUNCDATA", LTYPEF, AFUNCDATA,
|
||||
|
||||
0
|
||||
};
|
||||
|
||||
void
|
||||
cinit(void)
|
||||
{
|
||||
Sym *s;
|
||||
int i;
|
||||
|
||||
nullgen.type = D_NONE;
|
||||
nullgen.name = D_NONE;
|
||||
nullgen.reg = NREG;
|
||||
|
||||
nerrors = 0;
|
||||
iostack = I;
|
||||
iofree = I;
|
||||
peekc = IGN;
|
||||
nhunk = 0;
|
||||
for(i=0; i<NHASH; i++)
|
||||
hash[i] = S;
|
||||
for(i=0; itab[i].name; i++) {
|
||||
s = slookup(itab[i].name);
|
||||
s->type = itab[i].type;
|
||||
s->value = itab[i].value;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
syminit(Sym *s)
|
||||
{
|
||||
|
||||
s->type = LNAME;
|
||||
s->value = 0;
|
||||
}
|
||||
|
||||
int
|
||||
isreg(Addr *g)
|
||||
{
|
||||
|
||||
USED(g);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
cclean(void)
|
||||
{
|
||||
outcode(AEND, Always, &nullgen, NREG, &nullgen);
|
||||
}
|
||||
|
||||
static int bcode[] =
|
||||
{
|
||||
ABEQ,
|
||||
ABNE,
|
||||
ABCS,
|
||||
ABCC,
|
||||
ABMI,
|
||||
ABPL,
|
||||
ABVS,
|
||||
ABVC,
|
||||
ABHI,
|
||||
ABLS,
|
||||
ABGE,
|
||||
ABLT,
|
||||
ABGT,
|
||||
ABLE,
|
||||
AB,
|
||||
ANOP,
|
||||
};
|
||||
|
||||
static Prog *lastpc;
|
||||
|
||||
void
|
||||
outcode(int a, int scond, Addr *g1, int reg, Addr *g2)
|
||||
{
|
||||
Prog *p;
|
||||
Plist *pl;
|
||||
|
||||
/* hack to make B.NE etc. work: turn it into the corresponding conditional */
|
||||
if(a == AB){
|
||||
a = bcode[scond&0xf];
|
||||
scond = (scond & ~0xf) | Always;
|
||||
}
|
||||
|
||||
if(pass == 1)
|
||||
goto out;
|
||||
|
||||
p = malloc(sizeof *p);
|
||||
memset(p, 0, sizeof *p);
|
||||
p->as = a;
|
||||
p->lineno = stmtline;
|
||||
p->scond = scond;
|
||||
p->from = *g1;
|
||||
p->reg = reg;
|
||||
p->to = *g2;
|
||||
p->pc = pc;
|
||||
|
||||
if(lastpc == nil) {
|
||||
pl = linknewplist(ctxt);
|
||||
pl->firstpc = p;
|
||||
} else
|
||||
lastpc->link = p;
|
||||
lastpc = p;
|
||||
|
||||
out:
|
||||
if(a != AGLOBL && a != ADATA)
|
||||
pc++;
|
||||
}
|
||||
|
||||
#include "../cc/lexbody"
|
||||
#include "../cc/macbody"
|
||||
@@ -1,371 +0,0 @@
|
||||
// Inferno utils/5a/lex.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/5a/lex.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
//go:generate go tool yacc a.y
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"cmd/internal/asm"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/obj/arm"
|
||||
)
|
||||
|
||||
var (
|
||||
yyerror = asm.Yyerror
|
||||
nullgen obj.Addr
|
||||
stmtline int32
|
||||
)
|
||||
|
||||
const Always = arm.C_SCOND_NONE
|
||||
|
||||
func main() {
|
||||
cinit()
|
||||
|
||||
asm.LSCONST = LSCONST
|
||||
asm.LCONST = LCONST
|
||||
asm.LFCONST = LFCONST
|
||||
asm.LNAME = LNAME
|
||||
asm.LVAR = LVAR
|
||||
asm.LLAB = LLAB
|
||||
|
||||
asm.Lexinit = lexinit
|
||||
asm.Cclean = cclean
|
||||
asm.Yyparse = yyparse
|
||||
|
||||
asm.Thechar = '5'
|
||||
asm.Thestring = "arm"
|
||||
asm.Thelinkarch = &arm.Linkarm
|
||||
|
||||
asm.Main()
|
||||
}
|
||||
|
||||
type yy struct{}
|
||||
|
||||
func (yy) Lex(v *yySymType) int {
|
||||
var av asm.Yylval
|
||||
tok := asm.Yylex(&av)
|
||||
v.sym = av.Sym
|
||||
v.lval = int32(av.Lval)
|
||||
v.sval = av.Sval
|
||||
v.dval = av.Dval
|
||||
return tok
|
||||
}
|
||||
|
||||
func (yy) Error(msg string) {
|
||||
asm.Yyerror("%s", msg)
|
||||
}
|
||||
|
||||
func yyparse() {
|
||||
yyParse(yy{})
|
||||
}
|
||||
|
||||
var lexinit = []asm.Lextab{
|
||||
{"SP", LSP, obj.NAME_AUTO},
|
||||
{"SB", LSB, obj.NAME_EXTERN},
|
||||
{"FP", LFP, obj.NAME_PARAM},
|
||||
{"PC", LPC, obj.TYPE_BRANCH},
|
||||
|
||||
{"R", LR, 0},
|
||||
|
||||
{"R0", LREG, arm.REG_R0},
|
||||
{"R1", LREG, arm.REG_R1},
|
||||
{"R2", LREG, arm.REG_R2},
|
||||
{"R3", LREG, arm.REG_R3},
|
||||
{"R4", LREG, arm.REG_R4},
|
||||
{"R5", LREG, arm.REG_R5},
|
||||
{"R6", LREG, arm.REG_R6},
|
||||
{"R7", LREG, arm.REG_R7},
|
||||
{"R8", LREG, arm.REG_R8},
|
||||
{"R9", LREG, arm.REG_R9},
|
||||
{"g", LREG, arm.REG_R10}, // avoid unintentionally clobber g using R10
|
||||
{"R11", LREG, arm.REG_R11},
|
||||
{"R12", LREG, arm.REG_R12},
|
||||
{"R13", LREG, arm.REG_R13},
|
||||
{"R14", LREG, arm.REG_R14},
|
||||
{"R15", LREG, arm.REG_R15},
|
||||
{"F", LF, 0},
|
||||
{"F0", LFREG, arm.REG_F0},
|
||||
{"F1", LFREG, arm.REG_F1},
|
||||
{"F2", LFREG, arm.REG_F2},
|
||||
{"F3", LFREG, arm.REG_F3},
|
||||
{"F4", LFREG, arm.REG_F4},
|
||||
{"F5", LFREG, arm.REG_F5},
|
||||
{"F6", LFREG, arm.REG_F6},
|
||||
{"F7", LFREG, arm.REG_F7},
|
||||
{"F8", LFREG, arm.REG_F8},
|
||||
{"F9", LFREG, arm.REG_F9},
|
||||
{"F10", LFREG, arm.REG_F10},
|
||||
{"F11", LFREG, arm.REG_F11},
|
||||
{"F12", LFREG, arm.REG_F12},
|
||||
{"F13", LFREG, arm.REG_F13},
|
||||
{"F14", LFREG, arm.REG_F14},
|
||||
{"F15", LFREG, arm.REG_F15},
|
||||
{"C", LC, 0},
|
||||
{"C0", LCREG, 0},
|
||||
{"C1", LCREG, 1},
|
||||
{"C2", LCREG, 2},
|
||||
{"C3", LCREG, 3},
|
||||
{"C4", LCREG, 4},
|
||||
{"C5", LCREG, 5},
|
||||
{"C6", LCREG, 6},
|
||||
{"C7", LCREG, 7},
|
||||
{"C8", LCREG, 8},
|
||||
{"C9", LCREG, 9},
|
||||
{"C10", LCREG, 10},
|
||||
{"C11", LCREG, 11},
|
||||
{"C12", LCREG, 12},
|
||||
{"C13", LCREG, 13},
|
||||
{"C14", LCREG, 14},
|
||||
{"C15", LCREG, 15},
|
||||
{"CPSR", LPSR, arm.REG_CPSR},
|
||||
{"SPSR", LPSR, arm.REG_SPSR},
|
||||
{"FPSR", LFCR, arm.REG_FPSR},
|
||||
{"FPCR", LFCR, arm.REG_FPCR},
|
||||
{".EQ", LCOND, arm.C_SCOND_EQ},
|
||||
{".NE", LCOND, arm.C_SCOND_NE},
|
||||
{".CS", LCOND, arm.C_SCOND_HS},
|
||||
{".HS", LCOND, arm.C_SCOND_HS},
|
||||
{".CC", LCOND, arm.C_SCOND_LO},
|
||||
{".LO", LCOND, arm.C_SCOND_LO},
|
||||
{".MI", LCOND, arm.C_SCOND_MI},
|
||||
{".PL", LCOND, arm.C_SCOND_PL},
|
||||
{".VS", LCOND, arm.C_SCOND_VS},
|
||||
{".VC", LCOND, arm.C_SCOND_VC},
|
||||
{".HI", LCOND, arm.C_SCOND_HI},
|
||||
{".LS", LCOND, arm.C_SCOND_LS},
|
||||
{".GE", LCOND, arm.C_SCOND_GE},
|
||||
{".LT", LCOND, arm.C_SCOND_LT},
|
||||
{".GT", LCOND, arm.C_SCOND_GT},
|
||||
{".LE", LCOND, arm.C_SCOND_LE},
|
||||
{".AL", LCOND, arm.C_SCOND_NONE},
|
||||
{".U", LS, arm.C_UBIT},
|
||||
{".S", LS, arm.C_SBIT},
|
||||
{".W", LS, arm.C_WBIT},
|
||||
{".P", LS, arm.C_PBIT},
|
||||
{".PW", LS, arm.C_WBIT | arm.C_PBIT},
|
||||
{".WP", LS, arm.C_WBIT | arm.C_PBIT},
|
||||
{".F", LS, arm.C_FBIT},
|
||||
{".IBW", LS, arm.C_WBIT | arm.C_PBIT | arm.C_UBIT},
|
||||
{".IAW", LS, arm.C_WBIT | arm.C_UBIT},
|
||||
{".DBW", LS, arm.C_WBIT | arm.C_PBIT},
|
||||
{".DAW", LS, arm.C_WBIT},
|
||||
{".IB", LS, arm.C_PBIT | arm.C_UBIT},
|
||||
{".IA", LS, arm.C_UBIT},
|
||||
{".DB", LS, arm.C_PBIT},
|
||||
{".DA", LS, 0},
|
||||
{"@", LAT, 0},
|
||||
{"AND", LTYPE1, arm.AAND},
|
||||
{"EOR", LTYPE1, arm.AEOR},
|
||||
{"SUB", LTYPE1, arm.ASUB},
|
||||
{"RSB", LTYPE1, arm.ARSB},
|
||||
{"ADD", LTYPE1, arm.AADD},
|
||||
{"ADC", LTYPE1, arm.AADC},
|
||||
{"SBC", LTYPE1, arm.ASBC},
|
||||
{"RSC", LTYPE1, arm.ARSC},
|
||||
{"ORR", LTYPE1, arm.AORR},
|
||||
{"BIC", LTYPE1, arm.ABIC},
|
||||
{"SLL", LTYPE1, arm.ASLL},
|
||||
{"SRL", LTYPE1, arm.ASRL},
|
||||
{"SRA", LTYPE1, arm.ASRA},
|
||||
{"MUL", LTYPE1, arm.AMUL},
|
||||
{"MULA", LTYPEN, arm.AMULA},
|
||||
{"DIV", LTYPE1, arm.ADIV},
|
||||
{"MOD", LTYPE1, arm.AMOD},
|
||||
{"MULL", LTYPEM, arm.AMULL},
|
||||
{"MULAL", LTYPEM, arm.AMULAL},
|
||||
{"MULLU", LTYPEM, arm.AMULLU},
|
||||
{"MULALU", LTYPEM, arm.AMULALU},
|
||||
{"MVN", LTYPE2, arm.AMVN}, /* op2 ignored */
|
||||
{"MOVB", LTYPE3, arm.AMOVB},
|
||||
{"MOVBU", LTYPE3, arm.AMOVBU},
|
||||
{"MOVH", LTYPE3, arm.AMOVH},
|
||||
{"MOVHU", LTYPE3, arm.AMOVHU},
|
||||
{"MOVW", LTYPE3, arm.AMOVW},
|
||||
{"MOVD", LTYPE3, arm.AMOVD},
|
||||
{"MOVDF", LTYPE3, arm.AMOVDF},
|
||||
{"MOVDW", LTYPE3, arm.AMOVDW},
|
||||
{"MOVF", LTYPE3, arm.AMOVF},
|
||||
{"MOVFD", LTYPE3, arm.AMOVFD},
|
||||
{"MOVFW", LTYPE3, arm.AMOVFW},
|
||||
{"MOVWD", LTYPE3, arm.AMOVWD},
|
||||
{"MOVWF", LTYPE3, arm.AMOVWF},
|
||||
{"LDREX", LTYPE3, arm.ALDREX},
|
||||
{"LDREXD", LTYPE3, arm.ALDREXD},
|
||||
{"STREX", LTYPE9, arm.ASTREX},
|
||||
{"STREXD", LTYPE9, arm.ASTREXD},
|
||||
|
||||
/*
|
||||
{"NEGF", LTYPEI, ANEGF},
|
||||
{"NEGD", LTYPEI, ANEGD},
|
||||
{"SQTF", LTYPEI, ASQTF},
|
||||
{"SQTD", LTYPEI, ASQTD},
|
||||
{"RNDF", LTYPEI, ARNDF},
|
||||
{"RNDD", LTYPEI, ARNDD},
|
||||
{"URDF", LTYPEI, AURDF},
|
||||
{"URDD", LTYPEI, AURDD},
|
||||
{"NRMF", LTYPEI, ANRMF},
|
||||
{"NRMD", LTYPEI, ANRMD},
|
||||
*/
|
||||
{"ABSF", LTYPEI, arm.AABSF},
|
||||
{"ABSD", LTYPEI, arm.AABSD},
|
||||
{"SQRTF", LTYPEI, arm.ASQRTF},
|
||||
{"SQRTD", LTYPEI, arm.ASQRTD},
|
||||
{"CMPF", LTYPEL, arm.ACMPF},
|
||||
{"CMPD", LTYPEL, arm.ACMPD},
|
||||
{"ADDF", LTYPEK, arm.AADDF},
|
||||
{"ADDD", LTYPEK, arm.AADDD},
|
||||
{"SUBF", LTYPEK, arm.ASUBF},
|
||||
{"SUBD", LTYPEK, arm.ASUBD},
|
||||
{"MULF", LTYPEK, arm.AMULF},
|
||||
{"MULD", LTYPEK, arm.AMULD},
|
||||
{"DIVF", LTYPEK, arm.ADIVF},
|
||||
{"DIVD", LTYPEK, arm.ADIVD},
|
||||
{"B", LTYPE4, arm.AB},
|
||||
{"BL", LTYPE4, arm.ABL},
|
||||
{"BX", LTYPEBX, arm.ABX},
|
||||
{"BEQ", LTYPE5, arm.ABEQ},
|
||||
{"BNE", LTYPE5, arm.ABNE},
|
||||
{"BCS", LTYPE5, arm.ABCS},
|
||||
{"BHS", LTYPE5, arm.ABHS},
|
||||
{"BCC", LTYPE5, arm.ABCC},
|
||||
{"BLO", LTYPE5, arm.ABLO},
|
||||
{"BMI", LTYPE5, arm.ABMI},
|
||||
{"BPL", LTYPE5, arm.ABPL},
|
||||
{"BVS", LTYPE5, arm.ABVS},
|
||||
{"BVC", LTYPE5, arm.ABVC},
|
||||
{"BHI", LTYPE5, arm.ABHI},
|
||||
{"BLS", LTYPE5, arm.ABLS},
|
||||
{"BGE", LTYPE5, arm.ABGE},
|
||||
{"BLT", LTYPE5, arm.ABLT},
|
||||
{"BGT", LTYPE5, arm.ABGT},
|
||||
{"BLE", LTYPE5, arm.ABLE},
|
||||
{"BCASE", LTYPE5, arm.ABCASE},
|
||||
{"SWI", LTYPE6, arm.ASWI},
|
||||
{"CMP", LTYPE7, arm.ACMP},
|
||||
{"TST", LTYPE7, arm.ATST},
|
||||
{"TEQ", LTYPE7, arm.ATEQ},
|
||||
{"CMN", LTYPE7, arm.ACMN},
|
||||
{"MOVM", LTYPE8, arm.AMOVM},
|
||||
{"SWPBU", LTYPE9, arm.ASWPBU},
|
||||
{"SWPW", LTYPE9, arm.ASWPW},
|
||||
{"RET", LTYPEA, obj.ARET},
|
||||
{"RFE", LTYPEA, arm.ARFE},
|
||||
{"TEXT", LTYPEB, obj.ATEXT},
|
||||
{"GLOBL", LGLOBL, obj.AGLOBL},
|
||||
{"DATA", LTYPEC, obj.ADATA},
|
||||
{"CASE", LTYPED, arm.ACASE},
|
||||
{"END", LTYPEE, obj.AEND},
|
||||
{"WORD", LTYPEH, arm.AWORD},
|
||||
{"NOP", LTYPEI, obj.ANOP},
|
||||
{"MCR", LTYPEJ, 0},
|
||||
{"MRC", LTYPEJ, 1},
|
||||
{"PLD", LTYPEPLD, arm.APLD},
|
||||
{"UNDEF", LTYPEE, obj.AUNDEF},
|
||||
{"CLZ", LTYPE2, arm.ACLZ},
|
||||
{"MULWT", LTYPE1, arm.AMULWT},
|
||||
{"MULWB", LTYPE1, arm.AMULWB},
|
||||
{"MULAWT", LTYPEN, arm.AMULAWT},
|
||||
{"MULAWB", LTYPEN, arm.AMULAWB},
|
||||
{"USEFIELD", LTYPEN, obj.AUSEFIELD},
|
||||
{"PCDATA", LTYPEPC, obj.APCDATA},
|
||||
{"FUNCDATA", LTYPEF, obj.AFUNCDATA},
|
||||
}
|
||||
|
||||
func cinit() {
|
||||
}
|
||||
|
||||
func isreg(g *obj.Addr) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func cclean() {
|
||||
outcode(obj.AEND, Always, &nullgen, 0, &nullgen)
|
||||
}
|
||||
|
||||
var bcode = []int{
|
||||
arm.ABEQ,
|
||||
arm.ABNE,
|
||||
arm.ABCS,
|
||||
arm.ABCC,
|
||||
arm.ABMI,
|
||||
arm.ABPL,
|
||||
arm.ABVS,
|
||||
arm.ABVC,
|
||||
arm.ABHI,
|
||||
arm.ABLS,
|
||||
arm.ABGE,
|
||||
arm.ABLT,
|
||||
arm.ABGT,
|
||||
arm.ABLE,
|
||||
arm.AB,
|
||||
obj.ANOP,
|
||||
}
|
||||
|
||||
var lastpc *obj.Prog
|
||||
|
||||
func outcode(a, scond int32, g1 *obj.Addr, reg int32, g2 *obj.Addr) {
|
||||
var p *obj.Prog
|
||||
var pl *obj.Plist
|
||||
|
||||
/* hack to make B.NE etc. work: turn it into the corresponding conditional */
|
||||
if a == arm.AB {
|
||||
a = int32(bcode[(scond^arm.C_SCOND_XOR)&0xf])
|
||||
scond = (scond &^ 0xf) | Always
|
||||
}
|
||||
|
||||
if asm.Pass == 1 {
|
||||
goto out
|
||||
}
|
||||
|
||||
p = new(obj.Prog)
|
||||
*p = obj.Prog{}
|
||||
p.Ctxt = asm.Ctxt
|
||||
p.As = int16(a)
|
||||
p.Lineno = stmtline
|
||||
p.Scond = uint8(scond)
|
||||
p.From = *g1
|
||||
p.Reg = int16(reg)
|
||||
p.To = *g2
|
||||
p.Pc = int64(asm.PC)
|
||||
|
||||
if lastpc == nil {
|
||||
pl = obj.Linknewplist(asm.Ctxt)
|
||||
pl.Firstpc = p
|
||||
} else {
|
||||
lastpc.Link = p
|
||||
}
|
||||
lastpc = p
|
||||
|
||||
out:
|
||||
if a != obj.AGLOBL && a != obj.ADATA {
|
||||
asm.PC++
|
||||
}
|
||||
}
|
||||
1362
src/cmd/5a/y.go
1362
src/cmd/5a/y.go
File diff suppressed because it is too large
Load Diff
2936
src/cmd/5a/y.tab.c
Normal file
2936
src/cmd/5a/y.tab.c
Normal file
File diff suppressed because it is too large
Load Diff
188
src/cmd/5a/y.tab.h
Normal file
188
src/cmd/5a/y.tab.h
Normal file
@@ -0,0 +1,188 @@
|
||||
/* A Bison parser, made by GNU Bison 2.7.12-4996. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
#ifndef YY_YY_Y_TAB_H_INCLUDED
|
||||
# define YY_YY_Y_TAB_H_INCLUDED
|
||||
/* Enabling traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 0
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int yydebug;
|
||||
#endif
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
LTYPE1 = 258,
|
||||
LTYPE2 = 259,
|
||||
LTYPE3 = 260,
|
||||
LTYPE4 = 261,
|
||||
LTYPE5 = 262,
|
||||
LTYPE6 = 263,
|
||||
LTYPE7 = 264,
|
||||
LTYPE8 = 265,
|
||||
LTYPE9 = 266,
|
||||
LTYPEA = 267,
|
||||
LTYPEB = 268,
|
||||
LTYPEC = 269,
|
||||
LTYPED = 270,
|
||||
LTYPEE = 271,
|
||||
LTYPEG = 272,
|
||||
LTYPEH = 273,
|
||||
LTYPEI = 274,
|
||||
LTYPEJ = 275,
|
||||
LTYPEK = 276,
|
||||
LTYPEL = 277,
|
||||
LTYPEM = 278,
|
||||
LTYPEN = 279,
|
||||
LTYPEBX = 280,
|
||||
LTYPEPLD = 281,
|
||||
LCONST = 282,
|
||||
LSP = 283,
|
||||
LSB = 284,
|
||||
LFP = 285,
|
||||
LPC = 286,
|
||||
LTYPEX = 287,
|
||||
LTYPEPC = 288,
|
||||
LTYPEF = 289,
|
||||
LR = 290,
|
||||
LREG = 291,
|
||||
LF = 292,
|
||||
LFREG = 293,
|
||||
LC = 294,
|
||||
LCREG = 295,
|
||||
LPSR = 296,
|
||||
LFCR = 297,
|
||||
LCOND = 298,
|
||||
LS = 299,
|
||||
LAT = 300,
|
||||
LFCONST = 301,
|
||||
LSCONST = 302,
|
||||
LNAME = 303,
|
||||
LLAB = 304,
|
||||
LVAR = 305
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define LTYPE1 258
|
||||
#define LTYPE2 259
|
||||
#define LTYPE3 260
|
||||
#define LTYPE4 261
|
||||
#define LTYPE5 262
|
||||
#define LTYPE6 263
|
||||
#define LTYPE7 264
|
||||
#define LTYPE8 265
|
||||
#define LTYPE9 266
|
||||
#define LTYPEA 267
|
||||
#define LTYPEB 268
|
||||
#define LTYPEC 269
|
||||
#define LTYPED 270
|
||||
#define LTYPEE 271
|
||||
#define LTYPEG 272
|
||||
#define LTYPEH 273
|
||||
#define LTYPEI 274
|
||||
#define LTYPEJ 275
|
||||
#define LTYPEK 276
|
||||
#define LTYPEL 277
|
||||
#define LTYPEM 278
|
||||
#define LTYPEN 279
|
||||
#define LTYPEBX 280
|
||||
#define LTYPEPLD 281
|
||||
#define LCONST 282
|
||||
#define LSP 283
|
||||
#define LSB 284
|
||||
#define LFP 285
|
||||
#define LPC 286
|
||||
#define LTYPEX 287
|
||||
#define LTYPEPC 288
|
||||
#define LTYPEF 289
|
||||
#define LR 290
|
||||
#define LREG 291
|
||||
#define LF 292
|
||||
#define LFREG 293
|
||||
#define LC 294
|
||||
#define LCREG 295
|
||||
#define LPSR 296
|
||||
#define LFCR 297
|
||||
#define LCOND 298
|
||||
#define LS 299
|
||||
#define LAT 300
|
||||
#define LFCONST 301
|
||||
#define LSCONST 302
|
||||
#define LNAME 303
|
||||
#define LLAB 304
|
||||
#define LVAR 305
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE
|
||||
{
|
||||
/* Line 2053 of yacc.c */
|
||||
#line 39 "a.y"
|
||||
|
||||
Sym *sym;
|
||||
int32 lval;
|
||||
double dval;
|
||||
char sval[8];
|
||||
Addr addr;
|
||||
|
||||
|
||||
/* Line 2053 of yacc.c */
|
||||
#line 166 "y.tab.h"
|
||||
} YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
#ifdef YYPARSE_PARAM
|
||||
#if defined __STDC__ || defined __cplusplus
|
||||
int yyparse (void *YYPARSE_PARAM);
|
||||
#else
|
||||
int yyparse ();
|
||||
#endif
|
||||
#else /* ! YYPARSE_PARAM */
|
||||
#if defined __STDC__ || defined __cplusplus
|
||||
int yyparse (void);
|
||||
#else
|
||||
int yyparse ();
|
||||
#endif
|
||||
#endif /* ! YYPARSE_PARAM */
|
||||
|
||||
#endif /* !YY_YY_Y_TAB_H_INCLUDED */
|
||||
1213
src/cmd/5c/cgen.c
Normal file
1213
src/cmd/5c/cgen.c
Normal file
File diff suppressed because it is too large
Load Diff
16
src/cmd/5c/doc.go
Normal file
16
src/cmd/5c/doc.go
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build ignore
|
||||
|
||||
/*
|
||||
|
||||
5c is a version of the Plan 9 C compiler. The original is documented at
|
||||
|
||||
http://plan9.bell-labs.com/magic/man2html/1/8c
|
||||
|
||||
Its target architecture is the ARM, referred to by these tools as arm.
|
||||
|
||||
*/
|
||||
package main
|
||||
333
src/cmd/5c/gc.h
Normal file
333
src/cmd/5c/gc.h
Normal file
@@ -0,0 +1,333 @@
|
||||
// Inferno utils/5c/gc.h
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/5c/gc.h
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include <u.h>
|
||||
#include "../cc/cc.h"
|
||||
#include "../5l/5.out.h"
|
||||
|
||||
/*
|
||||
* 5c/arm
|
||||
* Arm 7500
|
||||
*/
|
||||
#define SZ_CHAR 1
|
||||
#define SZ_SHORT 2
|
||||
#define SZ_INT 4
|
||||
#define SZ_LONG 4
|
||||
#define SZ_IND 4
|
||||
#define SZ_FLOAT 4
|
||||
#define SZ_VLONG 8
|
||||
#define SZ_DOUBLE 8
|
||||
#define FNX 100
|
||||
|
||||
typedef struct Case Case;
|
||||
typedef struct C1 C1;
|
||||
typedef struct Multab Multab;
|
||||
typedef struct Hintab Hintab;
|
||||
typedef struct Reg Reg;
|
||||
typedef struct Rgn Rgn;
|
||||
|
||||
|
||||
#define R0ISZERO 0
|
||||
|
||||
#define A ((Addr*)0)
|
||||
|
||||
#define INDEXED 9
|
||||
#define P ((Prog*)0)
|
||||
|
||||
struct Case
|
||||
{
|
||||
Case* link;
|
||||
int32 val;
|
||||
int32 label;
|
||||
char def;
|
||||
char isv;
|
||||
};
|
||||
#define C ((Case*)0)
|
||||
|
||||
struct C1
|
||||
{
|
||||
int32 val;
|
||||
int32 label;
|
||||
};
|
||||
|
||||
struct Multab
|
||||
{
|
||||
int32 val;
|
||||
char code[20];
|
||||
};
|
||||
|
||||
struct Hintab
|
||||
{
|
||||
ushort val;
|
||||
char hint[10];
|
||||
};
|
||||
|
||||
struct Reg
|
||||
{
|
||||
int32 pc;
|
||||
int32 rpo; /* reverse post ordering */
|
||||
|
||||
Bits set;
|
||||
Bits use1;
|
||||
Bits use2;
|
||||
|
||||
Bits refbehind;
|
||||
Bits refahead;
|
||||
Bits calbehind;
|
||||
Bits calahead;
|
||||
Bits regdiff;
|
||||
Bits act;
|
||||
|
||||
int32 regu;
|
||||
int32 loop; /* could be shorter */
|
||||
|
||||
|
||||
Reg* log5;
|
||||
int32 active;
|
||||
|
||||
Reg* p1;
|
||||
Reg* p2;
|
||||
Reg* p2link;
|
||||
Reg* s1;
|
||||
Reg* s2;
|
||||
Reg* link;
|
||||
Prog* prog;
|
||||
};
|
||||
#define R ((Reg*)0)
|
||||
|
||||
#define NRGN 600
|
||||
struct Rgn
|
||||
{
|
||||
Reg* enter;
|
||||
short cost;
|
||||
short varno;
|
||||
short regno;
|
||||
};
|
||||
|
||||
EXTERN int32 breakpc;
|
||||
EXTERN int32 nbreak;
|
||||
EXTERN Case* cases;
|
||||
EXTERN Node constnode;
|
||||
EXTERN Node fconstnode;
|
||||
EXTERN int32 continpc;
|
||||
EXTERN int32 curarg;
|
||||
EXTERN int32 cursafe;
|
||||
EXTERN int32 isbigendian;
|
||||
EXTERN Prog* lastp;
|
||||
EXTERN int32 maxargsafe;
|
||||
EXTERN int mnstring;
|
||||
EXTERN Multab multab[20];
|
||||
extern int hintabsize;
|
||||
EXTERN Node* nodrat;
|
||||
EXTERN Node* nodret;
|
||||
EXTERN Node* nodsafe;
|
||||
EXTERN int32 nrathole;
|
||||
EXTERN int32 nstring;
|
||||
EXTERN Prog* p;
|
||||
EXTERN int32 pc;
|
||||
EXTERN Node regnode;
|
||||
EXTERN char string[NSNAME];
|
||||
EXTERN Sym* symrathole;
|
||||
EXTERN Node znode;
|
||||
EXTERN Prog zprog;
|
||||
EXTERN char reg[NREG+NFREG];
|
||||
EXTERN int32 exregoffset;
|
||||
EXTERN int32 exfregoffset;
|
||||
EXTERN int suppress;
|
||||
|
||||
#define BLOAD(r) band(bnot(r->refbehind), r->refahead)
|
||||
#define BSTORE(r) band(bnot(r->calbehind), r->calahead)
|
||||
#define LOAD(r) (~r->refbehind.b[z] & r->refahead.b[z])
|
||||
#define STORE(r) (~r->calbehind.b[z] & r->calahead.b[z])
|
||||
|
||||
#define bset(a,n) ((a).b[(n)/32]&(1L<<(n)%32))
|
||||
|
||||
#define CLOAD 4
|
||||
#define CREF 5
|
||||
#define CINF 1000
|
||||
#define LOOP 3
|
||||
|
||||
EXTERN Rgn region[NRGN];
|
||||
EXTERN Rgn* rgp;
|
||||
EXTERN int nregion;
|
||||
EXTERN int nvar;
|
||||
|
||||
EXTERN Bits externs;
|
||||
EXTERN Bits params;
|
||||
EXTERN Bits consts;
|
||||
EXTERN Bits addrs;
|
||||
|
||||
EXTERN int32 regbits;
|
||||
EXTERN int32 exregbits;
|
||||
|
||||
EXTERN int change;
|
||||
|
||||
EXTERN Reg* firstr;
|
||||
EXTERN Reg* lastr;
|
||||
EXTERN Reg zreg;
|
||||
EXTERN Reg* freer;
|
||||
EXTERN int32* idom;
|
||||
EXTERN Reg** rpo2r;
|
||||
EXTERN int32 maxnr;
|
||||
|
||||
extern char* anames[];
|
||||
extern Hintab hintab[];
|
||||
|
||||
/*
|
||||
* sgen.c
|
||||
*/
|
||||
void codgen(Node*, Node*);
|
||||
void gen(Node*);
|
||||
void noretval(int);
|
||||
void usedset(Node*, int);
|
||||
void xcom(Node*);
|
||||
int bcomplex(Node*, Node*);
|
||||
Prog* gtext(Sym*, int32);
|
||||
vlong argsize(int);
|
||||
|
||||
/*
|
||||
* cgen.c
|
||||
*/
|
||||
void cgen(Node*, Node*);
|
||||
void reglcgen(Node*, Node*, Node*);
|
||||
void lcgen(Node*, Node*);
|
||||
void bcgen(Node*, int);
|
||||
void boolgen(Node*, int, Node*);
|
||||
void sugen(Node*, Node*, int32);
|
||||
void layout(Node*, Node*, int, int, Node*);
|
||||
void cgenrel(Node*, Node*);
|
||||
|
||||
/*
|
||||
* txt.c
|
||||
*/
|
||||
void ginit(void);
|
||||
void gclean(void);
|
||||
void nextpc(void);
|
||||
void gargs(Node*, Node*, Node*);
|
||||
void garg1(Node*, Node*, Node*, int, Node**);
|
||||
Node* nodconst(int32);
|
||||
Node* nod32const(vlong);
|
||||
Node* nodfconst(double);
|
||||
void nodreg(Node*, Node*, int);
|
||||
void regret(Node*, Node*, Type*, int);
|
||||
int tmpreg(void);
|
||||
void regalloc(Node*, Node*, Node*);
|
||||
void regfree(Node*);
|
||||
void regialloc(Node*, Node*, Node*);
|
||||
void regsalloc(Node*, Node*);
|
||||
void regaalloc1(Node*, Node*);
|
||||
void regaalloc(Node*, Node*);
|
||||
void regind(Node*, Node*);
|
||||
void gprep(Node*, Node*);
|
||||
void raddr(Node*, Prog*);
|
||||
void naddr(Node*, Addr*);
|
||||
void gmovm(Node*, Node*, int);
|
||||
void gmove(Node*, Node*);
|
||||
void gmover(Node*, Node*);
|
||||
void gins(int a, Node*, Node*);
|
||||
void gopcode(int, Node*, Node*, Node*);
|
||||
int samaddr(Node*, Node*);
|
||||
void gbranch(int);
|
||||
void patch(Prog*, int32);
|
||||
int sconst(Node*);
|
||||
int sval(int32);
|
||||
void gpseudo(int, Sym*, Node*);
|
||||
void gprefetch(Node*);
|
||||
void gpcdata(int, int);
|
||||
|
||||
/*
|
||||
* swt.c
|
||||
*/
|
||||
int swcmp(const void*, const void*);
|
||||
void doswit(Node*);
|
||||
void swit1(C1*, int, int32, Node*);
|
||||
void swit2(C1*, int, int32, Node*);
|
||||
void newcase(void);
|
||||
void bitload(Node*, Node*, Node*, Node*, Node*);
|
||||
void bitstore(Node*, Node*, Node*, Node*, Node*);
|
||||
int mulcon(Node*, Node*);
|
||||
Multab* mulcon0(int32);
|
||||
void nullwarn(Node*, Node*);
|
||||
void outcode(void);
|
||||
|
||||
/*
|
||||
* list
|
||||
*/
|
||||
void listinit(void);
|
||||
|
||||
/*
|
||||
* reg.c
|
||||
*/
|
||||
Reg* rega(void);
|
||||
int rcmp(const void*, const void*);
|
||||
void regopt(Prog*);
|
||||
void addmove(Reg*, int, int, int);
|
||||
Bits mkvar(Addr*, int);
|
||||
void prop(Reg*, Bits, Bits);
|
||||
void loopit(Reg*, int32);
|
||||
void synch(Reg*, Bits);
|
||||
uint32 allreg(uint32, Rgn*);
|
||||
void paint1(Reg*, int);
|
||||
uint32 paint2(Reg*, int);
|
||||
void paint3(Reg*, int, int32, int);
|
||||
void addreg(Addr*, int);
|
||||
|
||||
/*
|
||||
* peep.c
|
||||
*/
|
||||
void peep(void);
|
||||
void excise(Reg*);
|
||||
Reg* uniqp(Reg*);
|
||||
Reg* uniqs(Reg*);
|
||||
int regtyp(Addr*);
|
||||
int regzer(Addr*);
|
||||
int anyvar(Addr*);
|
||||
int subprop(Reg*);
|
||||
int copyprop(Reg*);
|
||||
int shiftprop(Reg*);
|
||||
void constprop(Addr*, Addr*, Reg*);
|
||||
int copy1(Addr*, Addr*, Reg*, int);
|
||||
int copyu(Prog*, Addr*, Addr*);
|
||||
|
||||
int copyas(Addr*, Addr*);
|
||||
int copyau(Addr*, Addr*);
|
||||
int copyau1(Prog*, Addr*);
|
||||
int copysub(Addr*, Addr*, Addr*, int);
|
||||
int copysub1(Prog*, Addr*, Addr*, int);
|
||||
|
||||
int32 RtoB(int);
|
||||
int32 FtoB(int);
|
||||
int BtoR(int32);
|
||||
int BtoF(int32);
|
||||
|
||||
void predicate(void);
|
||||
int isbranch(Prog *);
|
||||
int predicable(Prog *p);
|
||||
int modifiescpsr(Prog *p);
|
||||
@@ -1,5 +1,5 @@
|
||||
// Inferno utils/5l/list.h
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/5l/list.c
|
||||
// Inferno utils/5c/list.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/5c/list.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||
@@ -28,13 +28,12 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
// Printing.
|
||||
|
||||
#include "l.h"
|
||||
#include "../ld/lib.h"
|
||||
#define EXTERN
|
||||
#include "gc.h"
|
||||
|
||||
void
|
||||
listinit(void)
|
||||
{
|
||||
listinit9();
|
||||
listinit5();
|
||||
}
|
||||
640
src/cmd/5c/mul.c
Normal file
640
src/cmd/5c/mul.c
Normal file
@@ -0,0 +1,640 @@
|
||||
// Inferno utils/5c/mul.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/5c/mul.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
|
||||
#include "gc.h"
|
||||
|
||||
/*
|
||||
* code sequences for multiply by constant.
|
||||
* [a-l][0-3]
|
||||
* lsl $(A-'a'),r0,r1
|
||||
* [+][0-7]
|
||||
* add r0,r1,r2
|
||||
* [-][0-7]
|
||||
* sub r0,r1,r2
|
||||
*/
|
||||
|
||||
static int maxmulops = 3; /* max # of ops to replace mul with */
|
||||
static int multabp;
|
||||
static int32 mulval;
|
||||
static char* mulcp;
|
||||
static int32 valmax;
|
||||
static int shmax;
|
||||
|
||||
static int docode(char *hp, char *cp, int r0, int r1);
|
||||
static int gen1(int len);
|
||||
static int gen2(int len, int32 r1);
|
||||
static int gen3(int len, int32 r0, int32 r1, int flag);
|
||||
enum
|
||||
{
|
||||
SR1 = 1<<0, /* r1 has been shifted */
|
||||
SR0 = 1<<1, /* r0 has been shifted */
|
||||
UR1 = 1<<2, /* r1 has not been used */
|
||||
UR0 = 1<<3, /* r0 has not been used */
|
||||
};
|
||||
|
||||
Multab*
|
||||
mulcon0(int32 v)
|
||||
{
|
||||
int a1, a2, g;
|
||||
Multab *m, *m1;
|
||||
char hint[10];
|
||||
|
||||
if(v < 0)
|
||||
v = -v;
|
||||
|
||||
/*
|
||||
* look in cache
|
||||
*/
|
||||
m = multab;
|
||||
for(g=0; g<nelem(multab); g++) {
|
||||
if(m->val == v) {
|
||||
if(m->code[0] == 0)
|
||||
return 0;
|
||||
return m;
|
||||
}
|
||||
m++;
|
||||
}
|
||||
|
||||
/*
|
||||
* select a spot in cache to overwrite
|
||||
*/
|
||||
multabp++;
|
||||
if(multabp < 0 || multabp >= nelem(multab))
|
||||
multabp = 0;
|
||||
m = multab+multabp;
|
||||
m->val = v;
|
||||
mulval = v;
|
||||
|
||||
/*
|
||||
* look in execption hint table
|
||||
*/
|
||||
a1 = 0;
|
||||
a2 = hintabsize;
|
||||
for(;;) {
|
||||
if(a1 >= a2)
|
||||
goto no;
|
||||
g = (a2 + a1)/2;
|
||||
if(v < hintab[g].val) {
|
||||
a2 = g;
|
||||
continue;
|
||||
}
|
||||
if(v > hintab[g].val) {
|
||||
a1 = g+1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(docode(hintab[g].hint, m->code, 1, 0))
|
||||
return m;
|
||||
print("multiply table failure %d\n", v);
|
||||
m->code[0] = 0;
|
||||
return 0;
|
||||
|
||||
no:
|
||||
/*
|
||||
* try to search
|
||||
*/
|
||||
hint[0] = 0;
|
||||
for(g=1; g<=maxmulops; g++) {
|
||||
if(g >= maxmulops && v >= 65535)
|
||||
break;
|
||||
mulcp = hint+g;
|
||||
*mulcp = 0;
|
||||
if(gen1(g)) {
|
||||
if(docode(hint, m->code, 1, 0))
|
||||
return m;
|
||||
print("multiply table failure %d\n", v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* try a recur followed by a shift
|
||||
*/
|
||||
g = 0;
|
||||
while(!(v & 1)) {
|
||||
g++;
|
||||
v >>= 1;
|
||||
}
|
||||
if(g) {
|
||||
m1 = mulcon0(v);
|
||||
if(m1) {
|
||||
strcpy(m->code, m1->code);
|
||||
sprint(strchr(m->code, 0), "%c0", g+'a');
|
||||
return m;
|
||||
}
|
||||
}
|
||||
m->code[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
docode(char *hp, char *cp, int r0, int r1)
|
||||
{
|
||||
int c, i;
|
||||
|
||||
c = *hp++;
|
||||
*cp = c;
|
||||
cp += 2;
|
||||
switch(c) {
|
||||
default:
|
||||
c -= 'a';
|
||||
if(c < 1 || c >= 30)
|
||||
break;
|
||||
for(i=0; i<4; i++) {
|
||||
switch(i) {
|
||||
case 0:
|
||||
if(docode(hp, cp, r0<<c, r1))
|
||||
goto out;
|
||||
break;
|
||||
case 1:
|
||||
if(docode(hp, cp, r1<<c, r1))
|
||||
goto out;
|
||||
break;
|
||||
case 2:
|
||||
if(docode(hp, cp, r0, r0<<c))
|
||||
goto out;
|
||||
break;
|
||||
case 3:
|
||||
if(docode(hp, cp, r0, r1<<c))
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '+':
|
||||
for(i=0; i<8; i++) {
|
||||
cp[-1] = i+'0';
|
||||
switch(i) {
|
||||
case 1:
|
||||
if(docode(hp, cp, r0+r1, r1))
|
||||
goto out;
|
||||
break;
|
||||
case 5:
|
||||
if(docode(hp, cp, r0, r0+r1))
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '-':
|
||||
for(i=0; i<8; i++) {
|
||||
cp[-1] = i+'0';
|
||||
switch(i) {
|
||||
case 1:
|
||||
if(docode(hp, cp, r0-r1, r1))
|
||||
goto out;
|
||||
break;
|
||||
case 2:
|
||||
if(docode(hp, cp, r1-r0, r1))
|
||||
goto out;
|
||||
break;
|
||||
case 5:
|
||||
if(docode(hp, cp, r0, r0-r1))
|
||||
goto out;
|
||||
break;
|
||||
case 6:
|
||||
if(docode(hp, cp, r0, r1-r0))
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if(r0 == mulval)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
out:
|
||||
cp[-1] = i+'0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
gen1(int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(shmax=1; shmax<30; shmax++) {
|
||||
valmax = 1<<shmax;
|
||||
if(valmax >= mulval)
|
||||
break;
|
||||
}
|
||||
if(mulval == 1)
|
||||
return 1;
|
||||
|
||||
len--;
|
||||
for(i=1; i<=shmax; i++)
|
||||
if(gen2(len, 1<<i)) {
|
||||
*--mulcp = 'a'+i;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gen2(int len, int32 r1)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(len <= 0) {
|
||||
if(r1 == mulval)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
len--;
|
||||
if(len == 0)
|
||||
goto calcr0;
|
||||
|
||||
if(gen3(len, r1, r1+1, UR1)) {
|
||||
i = '+';
|
||||
goto out;
|
||||
}
|
||||
if(gen3(len, r1-1, r1, UR0)) {
|
||||
i = '-';
|
||||
goto out;
|
||||
}
|
||||
if(gen3(len, 1, r1+1, UR1)) {
|
||||
i = '+';
|
||||
goto out;
|
||||
}
|
||||
if(gen3(len, 1, r1-1, UR1)) {
|
||||
i = '-';
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
calcr0:
|
||||
if(mulval == r1+1) {
|
||||
i = '+';
|
||||
goto out;
|
||||
}
|
||||
if(mulval == r1-1) {
|
||||
i = '-';
|
||||
goto out;
|
||||
}
|
||||
return 0;
|
||||
|
||||
out:
|
||||
*--mulcp = i;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
gen3(int len, int32 r0, int32 r1, int flag)
|
||||
{
|
||||
int i, f1, f2;
|
||||
int32 x;
|
||||
|
||||
if(r0 <= 0 ||
|
||||
r0 >= r1 ||
|
||||
r1 > valmax)
|
||||
return 0;
|
||||
|
||||
len--;
|
||||
if(len == 0)
|
||||
goto calcr0;
|
||||
|
||||
if(!(flag & UR1)) {
|
||||
f1 = UR1|SR1;
|
||||
for(i=1; i<=shmax; i++) {
|
||||
x = r0<<i;
|
||||
if(x > valmax)
|
||||
break;
|
||||
if(gen3(len, r0, x, f1)) {
|
||||
i += 'a';
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!(flag & UR0)) {
|
||||
f1 = UR1|SR1;
|
||||
for(i=1; i<=shmax; i++) {
|
||||
x = r1<<i;
|
||||
if(x > valmax)
|
||||
break;
|
||||
if(gen3(len, r1, x, f1)) {
|
||||
i += 'a';
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!(flag & SR1)) {
|
||||
f1 = UR1|SR1|(flag&UR0);
|
||||
for(i=1; i<=shmax; i++) {
|
||||
x = r1<<i;
|
||||
if(x > valmax)
|
||||
break;
|
||||
if(gen3(len, r0, x, f1)) {
|
||||
i += 'a';
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!(flag & SR0)) {
|
||||
f1 = UR0|SR0|(flag&(SR1|UR1));
|
||||
|
||||
f2 = UR1|SR1;
|
||||
if(flag & UR1)
|
||||
f2 |= UR0;
|
||||
if(flag & SR1)
|
||||
f2 |= SR0;
|
||||
|
||||
for(i=1; i<=shmax; i++) {
|
||||
x = r0<<i;
|
||||
if(x > valmax)
|
||||
break;
|
||||
if(x > r1) {
|
||||
if(gen3(len, r1, x, f2)) {
|
||||
i += 'a';
|
||||
goto out;
|
||||
}
|
||||
} else
|
||||
if(gen3(len, x, r1, f1)) {
|
||||
i += 'a';
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x = r1+r0;
|
||||
if(gen3(len, r0, x, UR1)) {
|
||||
i = '+';
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(gen3(len, r1, x, UR1)) {
|
||||
i = '+';
|
||||
goto out;
|
||||
}
|
||||
|
||||
x = r1-r0;
|
||||
if(gen3(len, x, r1, UR0)) {
|
||||
i = '-';
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(x > r0) {
|
||||
if(gen3(len, r0, x, UR1)) {
|
||||
i = '-';
|
||||
goto out;
|
||||
}
|
||||
} else
|
||||
if(gen3(len, x, r0, UR0)) {
|
||||
i = '-';
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
calcr0:
|
||||
f1 = flag & (UR0|UR1);
|
||||
if(f1 == UR1) {
|
||||
for(i=1; i<=shmax; i++) {
|
||||
x = r1<<i;
|
||||
if(x >= mulval) {
|
||||
if(x == mulval) {
|
||||
i += 'a';
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(mulval == r1+r0) {
|
||||
i = '+';
|
||||
goto out;
|
||||
}
|
||||
if(mulval == r1-r0) {
|
||||
i = '-';
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
*--mulcp = i;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* hint table has numbers that
|
||||
* the search algorithm fails on.
|
||||
* <1000:
|
||||
* all numbers
|
||||
* <5000:
|
||||
* ÷ by 5
|
||||
* <10000:
|
||||
* ÷ by 50
|
||||
* <65536:
|
||||
* ÷ by 250
|
||||
*/
|
||||
Hintab hintab[] =
|
||||
{
|
||||
683, "b++d+e+",
|
||||
687, "b+e++e-",
|
||||
691, "b++d+e+",
|
||||
731, "b++d+e+",
|
||||
811, "b++d+i+",
|
||||
821, "b++e+e+",
|
||||
843, "b+d++e+",
|
||||
851, "b+f-+e-",
|
||||
853, "b++e+e+",
|
||||
877, "c++++g-",
|
||||
933, "b+c++g-",
|
||||
981, "c-+e-d+",
|
||||
1375, "b+c+b+h-",
|
||||
1675, "d+b++h+",
|
||||
2425, "c++f-e+",
|
||||
2675, "c+d++f-",
|
||||
2750, "b+d-b+h-",
|
||||
2775, "c-+g-e-",
|
||||
3125, "b++e+g+",
|
||||
3275, "b+c+g+e+",
|
||||
3350, "c++++i+",
|
||||
3475, "c-+e-f-",
|
||||
3525, "c-+d+g-",
|
||||
3625, "c-+e-j+",
|
||||
3675, "b+d+d+e+",
|
||||
3725, "b+d-+h+",
|
||||
3925, "b+d+f-d-",
|
||||
4275, "b+g++e+",
|
||||
4325, "b+h-+d+",
|
||||
4425, "b+b+g-j-",
|
||||
4525, "b+d-d+f+",
|
||||
4675, "c++d-g+",
|
||||
4775, "b+d+b+g-",
|
||||
4825, "c+c-+i-",
|
||||
4850, "c++++i-",
|
||||
4925, "b++e-g-",
|
||||
4975, "c+f++e-",
|
||||
5500, "b+g-c+d+",
|
||||
6700, "d+b++i+",
|
||||
9700, "d++++j-",
|
||||
11000, "b+f-c-h-",
|
||||
11750, "b+d+g+j-",
|
||||
12500, "b+c+e-k+",
|
||||
13250, "b+d+e-f+",
|
||||
13750, "b+h-c-d+",
|
||||
14250, "b+g-c+e-",
|
||||
14500, "c+f+j-d-",
|
||||
14750, "d-g--f+",
|
||||
16750, "b+e-d-n+",
|
||||
17750, "c+h-b+e+",
|
||||
18250, "d+b+h-d+",
|
||||
18750, "b+g-++f+",
|
||||
19250, "b+e+b+h+",
|
||||
19750, "b++h--f-",
|
||||
20250, "b+e-l-c+",
|
||||
20750, "c++bi+e-",
|
||||
21250, "b+i+l+c+",
|
||||
22000, "b+e+d-g-",
|
||||
22250, "b+d-h+k-",
|
||||
22750, "b+d-e-g+",
|
||||
23250, "b+c+h+e-",
|
||||
23500, "b+g-c-g-",
|
||||
23750, "b+g-b+h-",
|
||||
24250, "c++g+m-",
|
||||
24750, "b+e+e+j-",
|
||||
25000, "b++dh+g+",
|
||||
25250, "b+e+d-g-",
|
||||
25750, "b+e+b+j+",
|
||||
26250, "b+h+c+e+",
|
||||
26500, "b+h+c+g+",
|
||||
26750, "b+d+e+g-",
|
||||
27250, "b+e+e+f+",
|
||||
27500, "c-i-c-d+",
|
||||
27750, "b+bd++j+",
|
||||
28250, "d-d-++i-",
|
||||
28500, "c+c-h-e-",
|
||||
29000, "b+g-d-f+",
|
||||
29500, "c+h+++e-",
|
||||
29750, "b+g+f-c+",
|
||||
30250, "b+f-g-c+",
|
||||
33500, "c-f-d-n+",
|
||||
33750, "b+d-b+j-",
|
||||
34250, "c+e+++i+",
|
||||
35250, "e+b+d+k+",
|
||||
35500, "c+e+d-g-",
|
||||
35750, "c+i-++e+",
|
||||
36250, "b+bh-d+e+",
|
||||
36500, "c+c-h-e-",
|
||||
36750, "d+e--i+",
|
||||
37250, "b+g+g+b+",
|
||||
37500, "b+h-b+f+",
|
||||
37750, "c+be++j-",
|
||||
38500, "b+e+b+i+",
|
||||
38750, "d+i-b+d+",
|
||||
39250, "b+g-l-+d+",
|
||||
39500, "b+g-c+g-",
|
||||
39750, "b+bh-c+f-",
|
||||
40250, "b+bf+d+g-",
|
||||
40500, "b+g-c+g+",
|
||||
40750, "c+b+i-e+",
|
||||
41250, "d++bf+h+",
|
||||
41500, "b+j+c+d-",
|
||||
41750, "c+f+b+h-",
|
||||
42500, "c+h++g+",
|
||||
42750, "b+g+d-f-",
|
||||
43250, "b+l-e+d-",
|
||||
43750, "c+bd+h+f-",
|
||||
44000, "b+f+g-d-",
|
||||
44250, "b+d-g--f+",
|
||||
44500, "c+e+c+h+",
|
||||
44750, "b+e+d-h-",
|
||||
45250, "b++g+j-g+",
|
||||
45500, "c+d+e-g+",
|
||||
45750, "b+d-h-e-",
|
||||
46250, "c+bd++j+",
|
||||
46500, "b+d-c-j-",
|
||||
46750, "e-e-b+g-",
|
||||
47000, "b+c+d-j-",
|
||||
47250, "b+e+e-g-",
|
||||
47500, "b+g-c-h-",
|
||||
47750, "b+f-c+h-",
|
||||
48250, "d--h+n-",
|
||||
48500, "b+c-g+m-",
|
||||
48750, "b+e+e-g+",
|
||||
49500, "c-f+e+j-",
|
||||
49750, "c+c+g++f-",
|
||||
50000, "b+e+e+k+",
|
||||
50250, "b++i++g+",
|
||||
50500, "c+g+f-i+",
|
||||
50750, "b+e+d+k-",
|
||||
51500, "b+i+c-f+",
|
||||
51750, "b+bd+g-e-",
|
||||
52250, "b+d+g-j+",
|
||||
52500, "c+c+f+g+",
|
||||
52750, "b+c+e+i+",
|
||||
53000, "b+i+c+g+",
|
||||
53500, "c+g+g-n+",
|
||||
53750, "b+j+d-c+",
|
||||
54250, "b+d-g-j-",
|
||||
54500, "c-f+e+f+",
|
||||
54750, "b+f-+c+g+",
|
||||
55000, "b+g-d-g-",
|
||||
55250, "b+e+e+g+",
|
||||
55500, "b+cd++j+",
|
||||
55750, "b+bh-d-f-",
|
||||
56250, "c+d-b+j-",
|
||||
56500, "c+d+c+i+",
|
||||
56750, "b+e+d++h-",
|
||||
57000, "b+d+g-f+",
|
||||
57250, "b+f-m+d-",
|
||||
57750, "b+i+c+e-",
|
||||
58000, "b+e+d+h+",
|
||||
58250, "c+b+g+g+",
|
||||
58750, "d-e-j--e+",
|
||||
59000, "d-i-+e+",
|
||||
59250, "e--h-m+",
|
||||
59500, "c+c-h+f-",
|
||||
59750, "b+bh-e+i-",
|
||||
60250, "b+bh-e-e-",
|
||||
60500, "c+c-g-g-",
|
||||
60750, "b+e-l-e-",
|
||||
61250, "b+g-g-c+",
|
||||
61750, "b+g-c+g+",
|
||||
62250, "f--+c-i-",
|
||||
62750, "e+f--+g+",
|
||||
64750, "b+f+d+p-",
|
||||
};
|
||||
int hintabsize = nelem(hintab);
|
||||
1478
src/cmd/5c/peep.c
Normal file
1478
src/cmd/5c/peep.c
Normal file
File diff suppressed because it is too large
Load Diff
1210
src/cmd/5c/reg.c
Normal file
1210
src/cmd/5c/reg.c
Normal file
File diff suppressed because it is too large
Load Diff
265
src/cmd/5c/sgen.c
Normal file
265
src/cmd/5c/sgen.c
Normal file
@@ -0,0 +1,265 @@
|
||||
// Inferno utils/5c/sgen.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/5c/sgen.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
|
||||
#include "gc.h"
|
||||
|
||||
Prog*
|
||||
gtext(Sym *s, int32 stkoff)
|
||||
{
|
||||
int32 a;
|
||||
|
||||
a = argsize(1);
|
||||
if((textflag & NOSPLIT) != 0 && stkoff >= 128)
|
||||
yyerror("stack frame too large for NOSPLIT function");
|
||||
|
||||
gpseudo(ATEXT, s, nodconst(stkoff));
|
||||
p->to.type = D_CONST2;
|
||||
p->to.offset2 = a;
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
noretval(int n)
|
||||
{
|
||||
|
||||
if(n & 1) {
|
||||
gins(ANOP, Z, Z);
|
||||
p->to.type = D_REG;
|
||||
p->to.reg = REGRET;
|
||||
}
|
||||
if(n & 2) {
|
||||
gins(ANOP, Z, Z);
|
||||
p->to.type = D_FREG;
|
||||
p->to.reg = FREGRET;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* calculate addressability as follows
|
||||
* CONST ==> 20 $value
|
||||
* NAME ==> 10 name
|
||||
* REGISTER ==> 11 register
|
||||
* INDREG ==> 12 *[(reg)+offset]
|
||||
* &10 ==> 2 $name
|
||||
* ADD(2, 20) ==> 2 $name+offset
|
||||
* ADD(3, 20) ==> 3 $(reg)+offset
|
||||
* &12 ==> 3 $(reg)+offset
|
||||
* *11 ==> 11 ??
|
||||
* *2 ==> 10 name
|
||||
* *3 ==> 12 *(reg)+offset
|
||||
* calculate complexity (number of registers)
|
||||
*/
|
||||
void
|
||||
xcom(Node *n)
|
||||
{
|
||||
Node *l, *r;
|
||||
int t;
|
||||
|
||||
if(n == Z)
|
||||
return;
|
||||
l = n->left;
|
||||
r = n->right;
|
||||
n->addable = 0;
|
||||
n->complex = 0;
|
||||
switch(n->op) {
|
||||
case OCONST:
|
||||
n->addable = 20;
|
||||
return;
|
||||
|
||||
case OREGISTER:
|
||||
n->addable = 11;
|
||||
return;
|
||||
|
||||
case OINDREG:
|
||||
n->addable = 12;
|
||||
return;
|
||||
|
||||
case ONAME:
|
||||
n->addable = 10;
|
||||
return;
|
||||
|
||||
case OADDR:
|
||||
xcom(l);
|
||||
if(l->addable == 10)
|
||||
n->addable = 2;
|
||||
if(l->addable == 12)
|
||||
n->addable = 3;
|
||||
break;
|
||||
|
||||
case OIND:
|
||||
xcom(l);
|
||||
if(l->addable == 11)
|
||||
n->addable = 12;
|
||||
if(l->addable == 3)
|
||||
n->addable = 12;
|
||||
if(l->addable == 2)
|
||||
n->addable = 10;
|
||||
break;
|
||||
|
||||
case OADD:
|
||||
xcom(l);
|
||||
xcom(r);
|
||||
if(l->addable == 20) {
|
||||
if(r->addable == 2)
|
||||
n->addable = 2;
|
||||
if(r->addable == 3)
|
||||
n->addable = 3;
|
||||
}
|
||||
if(r->addable == 20) {
|
||||
if(l->addable == 2)
|
||||
n->addable = 2;
|
||||
if(l->addable == 3)
|
||||
n->addable = 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case OASLMUL:
|
||||
case OASMUL:
|
||||
xcom(l);
|
||||
xcom(r);
|
||||
t = vlog(r);
|
||||
if(t >= 0) {
|
||||
n->op = OASASHL;
|
||||
r->vconst = t;
|
||||
r->type = types[TINT];
|
||||
}
|
||||
break;
|
||||
|
||||
case OMUL:
|
||||
case OLMUL:
|
||||
xcom(l);
|
||||
xcom(r);
|
||||
t = vlog(r);
|
||||
if(t >= 0) {
|
||||
n->op = OASHL;
|
||||
r->vconst = t;
|
||||
r->type = types[TINT];
|
||||
}
|
||||
t = vlog(l);
|
||||
if(t >= 0) {
|
||||
n->op = OASHL;
|
||||
n->left = r;
|
||||
n->right = l;
|
||||
r = l;
|
||||
l = n->left;
|
||||
r->vconst = t;
|
||||
r->type = types[TINT];
|
||||
}
|
||||
break;
|
||||
|
||||
case OASLDIV:
|
||||
xcom(l);
|
||||
xcom(r);
|
||||
t = vlog(r);
|
||||
if(t >= 0) {
|
||||
n->op = OASLSHR;
|
||||
r->vconst = t;
|
||||
r->type = types[TINT];
|
||||
}
|
||||
break;
|
||||
|
||||
case OLDIV:
|
||||
xcom(l);
|
||||
xcom(r);
|
||||
t = vlog(r);
|
||||
if(t >= 0) {
|
||||
n->op = OLSHR;
|
||||
r->vconst = t;
|
||||
r->type = types[TINT];
|
||||
}
|
||||
break;
|
||||
|
||||
case OASLMOD:
|
||||
xcom(l);
|
||||
xcom(r);
|
||||
t = vlog(r);
|
||||
if(t >= 0) {
|
||||
n->op = OASAND;
|
||||
r->vconst--;
|
||||
}
|
||||
break;
|
||||
|
||||
case OLMOD:
|
||||
xcom(l);
|
||||
xcom(r);
|
||||
t = vlog(r);
|
||||
if(t >= 0) {
|
||||
n->op = OAND;
|
||||
r->vconst--;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if(l != Z)
|
||||
xcom(l);
|
||||
if(r != Z)
|
||||
xcom(r);
|
||||
break;
|
||||
}
|
||||
if(n->addable >= 10)
|
||||
return;
|
||||
|
||||
if(l != Z)
|
||||
n->complex = l->complex;
|
||||
if(r != Z) {
|
||||
if(r->complex == n->complex)
|
||||
n->complex = r->complex+1;
|
||||
else
|
||||
if(r->complex > n->complex)
|
||||
n->complex = r->complex;
|
||||
}
|
||||
if(n->complex == 0)
|
||||
n->complex++;
|
||||
|
||||
if(com64(n))
|
||||
return;
|
||||
|
||||
switch(n->op) {
|
||||
case OFUNC:
|
||||
n->complex = FNX;
|
||||
break;
|
||||
|
||||
case OADD:
|
||||
case OXOR:
|
||||
case OAND:
|
||||
case OOR:
|
||||
case OEQ:
|
||||
case ONE:
|
||||
/*
|
||||
* immediate operators, make const on right
|
||||
*/
|
||||
if(l->op == OCONST) {
|
||||
n->left = r;
|
||||
n->right = l;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
461
src/cmd/5c/swt.c
Normal file
461
src/cmd/5c/swt.c
Normal file
@@ -0,0 +1,461 @@
|
||||
// Inferno utils/5c/swt.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/5c/swt.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "gc.h"
|
||||
|
||||
void
|
||||
swit1(C1 *q, int nc, int32 def, Node *n)
|
||||
{
|
||||
Node nreg;
|
||||
|
||||
if(typev[n->type->etype]) {
|
||||
regsalloc(&nreg, n);
|
||||
nreg.type = types[TVLONG];
|
||||
cgen(n, &nreg);
|
||||
swit2(q, nc, def, &nreg);
|
||||
return;
|
||||
}
|
||||
|
||||
regalloc(&nreg, n, Z);
|
||||
nreg.type = types[TLONG];
|
||||
cgen(n, &nreg);
|
||||
swit2(q, nc, def, &nreg);
|
||||
regfree(&nreg);
|
||||
}
|
||||
|
||||
void
|
||||
swit2(C1 *q, int nc, int32 def, Node *n)
|
||||
{
|
||||
C1 *r;
|
||||
int i;
|
||||
int32 v;
|
||||
Prog *sp;
|
||||
|
||||
if(nc >= 3) {
|
||||
i = (q+nc-1)->val - (q+0)->val;
|
||||
if(!nacl && i > 0 && i < nc*2)
|
||||
goto direct;
|
||||
}
|
||||
if(nc < 5) {
|
||||
for(i=0; i<nc; i++) {
|
||||
if(debug['W'])
|
||||
print("case = %.8ux\n", q->val);
|
||||
gopcode(OEQ, nodconst(q->val), n, Z);
|
||||
patch(p, q->label);
|
||||
q++;
|
||||
}
|
||||
gbranch(OGOTO);
|
||||
patch(p, def);
|
||||
return;
|
||||
}
|
||||
|
||||
i = nc / 2;
|
||||
r = q+i;
|
||||
if(debug['W'])
|
||||
print("case > %.8ux\n", r->val);
|
||||
gopcode(OGT, nodconst(r->val), n, Z);
|
||||
sp = p;
|
||||
gopcode(OEQ, nodconst(r->val), n, Z); /* just gen the B.EQ */
|
||||
patch(p, r->label);
|
||||
swit2(q, i, def, n);
|
||||
|
||||
if(debug['W'])
|
||||
print("case < %.8ux\n", r->val);
|
||||
patch(sp, pc);
|
||||
swit2(r+1, nc-i-1, def, n);
|
||||
return;
|
||||
|
||||
direct:
|
||||
v = q->val;
|
||||
if(v != 0)
|
||||
gopcode(OSUB, nodconst(v), Z, n);
|
||||
gopcode(OCASE, nodconst((q+nc-1)->val - v), n, Z);
|
||||
patch(p, def);
|
||||
for(i=0; i<nc; i++) {
|
||||
if(debug['W'])
|
||||
print("case = %.8ux\n", q->val);
|
||||
while(q->val != v) {
|
||||
nextpc();
|
||||
p->as = ABCASE;
|
||||
patch(p, def);
|
||||
v++;
|
||||
}
|
||||
nextpc();
|
||||
p->as = ABCASE;
|
||||
patch(p, q->label);
|
||||
q++;
|
||||
v++;
|
||||
}
|
||||
gbranch(OGOTO); /* so that regopt() won't be confused */
|
||||
patch(p, def);
|
||||
}
|
||||
|
||||
void
|
||||
bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
|
||||
{
|
||||
int sh;
|
||||
int32 v;
|
||||
Node *l;
|
||||
|
||||
/*
|
||||
* n1 gets adjusted/masked value
|
||||
* n2 gets address of cell
|
||||
* n3 gets contents of cell
|
||||
*/
|
||||
l = b->left;
|
||||
if(n2 != Z) {
|
||||
regalloc(n1, l, nn);
|
||||
reglcgen(n2, l, Z);
|
||||
regalloc(n3, l, Z);
|
||||
gopcode(OAS, n2, Z, n3);
|
||||
gopcode(OAS, n3, Z, n1);
|
||||
} else {
|
||||
regalloc(n1, l, nn);
|
||||
cgen(l, n1);
|
||||
}
|
||||
if(b->type->shift == 0 && typeu[b->type->etype]) {
|
||||
v = ~0 + (1L << b->type->nbits);
|
||||
gopcode(OAND, nodconst(v), Z, n1);
|
||||
} else {
|
||||
sh = 32 - b->type->shift - b->type->nbits;
|
||||
if(sh > 0)
|
||||
gopcode(OASHL, nodconst(sh), Z, n1);
|
||||
sh += b->type->shift;
|
||||
if(sh > 0)
|
||||
if(typeu[b->type->etype])
|
||||
gopcode(OLSHR, nodconst(sh), Z, n1);
|
||||
else
|
||||
gopcode(OASHR, nodconst(sh), Z, n1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
|
||||
{
|
||||
int32 v;
|
||||
Node nod, *l;
|
||||
int sh;
|
||||
|
||||
/*
|
||||
* n1 has adjusted/masked value
|
||||
* n2 has address of cell
|
||||
* n3 has contents of cell
|
||||
*/
|
||||
l = b->left;
|
||||
regalloc(&nod, l, Z);
|
||||
v = ~0 + (1L << b->type->nbits);
|
||||
gopcode(OAND, nodconst(v), Z, n1);
|
||||
gopcode(OAS, n1, Z, &nod);
|
||||
if(nn != Z)
|
||||
gopcode(OAS, n1, Z, nn);
|
||||
sh = b->type->shift;
|
||||
if(sh > 0)
|
||||
gopcode(OASHL, nodconst(sh), Z, &nod);
|
||||
v <<= sh;
|
||||
gopcode(OAND, nodconst(~v), Z, n3);
|
||||
gopcode(OOR, n3, Z, &nod);
|
||||
gopcode(OAS, &nod, Z, n2);
|
||||
|
||||
regfree(&nod);
|
||||
regfree(n1);
|
||||
regfree(n2);
|
||||
regfree(n3);
|
||||
}
|
||||
|
||||
int32
|
||||
outstring(char *s, int32 n)
|
||||
{
|
||||
int32 r;
|
||||
|
||||
if(suppress)
|
||||
return nstring;
|
||||
r = nstring;
|
||||
while(n) {
|
||||
string[mnstring] = *s++;
|
||||
mnstring++;
|
||||
nstring++;
|
||||
if(mnstring >= NSNAME) {
|
||||
gpseudo(ADATA, symstring, nodconst(0L));
|
||||
p->from.offset += nstring - NSNAME;
|
||||
p->reg = NSNAME;
|
||||
p->to.type = D_SCONST;
|
||||
memmove(p->to.u.sval, string, NSNAME);
|
||||
mnstring = 0;
|
||||
}
|
||||
n--;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
mulcon(Node *n, Node *nn)
|
||||
{
|
||||
Node *l, *r, nod1, nod2;
|
||||
Multab *m;
|
||||
int32 v, vs;
|
||||
int o;
|
||||
char code[sizeof(m->code)+2], *p;
|
||||
|
||||
if(typefd[n->type->etype])
|
||||
return 0;
|
||||
l = n->left;
|
||||
r = n->right;
|
||||
if(l->op == OCONST) {
|
||||
l = r;
|
||||
r = n->left;
|
||||
}
|
||||
if(r->op != OCONST)
|
||||
return 0;
|
||||
v = convvtox(r->vconst, n->type->etype);
|
||||
if(v != r->vconst) {
|
||||
if(debug['M'])
|
||||
print("%L multiply conv: %lld\n", n->lineno, r->vconst);
|
||||
return 0;
|
||||
}
|
||||
m = mulcon0(v);
|
||||
if(!m) {
|
||||
if(debug['M'])
|
||||
print("%L multiply table: %lld\n", n->lineno, r->vconst);
|
||||
return 0;
|
||||
}
|
||||
if(debug['M'] && debug['v'])
|
||||
print("%L multiply: %d\n", n->lineno, v);
|
||||
|
||||
memmove(code, m->code, sizeof(m->code));
|
||||
code[sizeof(m->code)] = 0;
|
||||
|
||||
p = code;
|
||||
if(p[1] == 'i')
|
||||
p += 2;
|
||||
regalloc(&nod1, n, nn);
|
||||
cgen(l, &nod1);
|
||||
vs = v;
|
||||
regalloc(&nod2, n, Z);
|
||||
|
||||
loop:
|
||||
switch(*p) {
|
||||
case 0:
|
||||
regfree(&nod2);
|
||||
if(vs < 0) {
|
||||
gopcode(OAS, &nod1, Z, &nod1);
|
||||
gopcode(OSUB, &nod1, nodconst(0), nn);
|
||||
} else
|
||||
gopcode(OAS, &nod1, Z, nn);
|
||||
regfree(&nod1);
|
||||
return 1;
|
||||
case '+':
|
||||
o = OADD;
|
||||
goto addsub;
|
||||
case '-':
|
||||
o = OSUB;
|
||||
addsub: /* number is r,n,l */
|
||||
v = p[1] - '0';
|
||||
r = &nod1;
|
||||
if(v&4)
|
||||
r = &nod2;
|
||||
n = &nod1;
|
||||
if(v&2)
|
||||
n = &nod2;
|
||||
l = &nod1;
|
||||
if(v&1)
|
||||
l = &nod2;
|
||||
gopcode(o, l, n, r);
|
||||
break;
|
||||
default: /* op is shiftcount, number is r,l */
|
||||
v = p[1] - '0';
|
||||
r = &nod1;
|
||||
if(v&2)
|
||||
r = &nod2;
|
||||
l = &nod1;
|
||||
if(v&1)
|
||||
l = &nod2;
|
||||
v = *p - 'a';
|
||||
if(v < 0 || v >= 32) {
|
||||
diag(n, "mulcon unknown op: %c%c", p[0], p[1]);
|
||||
break;
|
||||
}
|
||||
gopcode(OASHL, nodconst(v), l, r);
|
||||
break;
|
||||
}
|
||||
p += 2;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
void
|
||||
sextern(Sym *s, Node *a, int32 o, int32 w)
|
||||
{
|
||||
int32 e, lw;
|
||||
|
||||
for(e=0; e<w; e+=NSNAME) {
|
||||
lw = NSNAME;
|
||||
if(w-e < lw)
|
||||
lw = w-e;
|
||||
gpseudo(ADATA, s, nodconst(0));
|
||||
p->from.offset += o+e;
|
||||
p->reg = lw;
|
||||
p->to.type = D_SCONST;
|
||||
memmove(p->to.u.sval, a->cstring+e, lw);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gextern(Sym *s, Node *a, int32 o, int32 w)
|
||||
{
|
||||
|
||||
if(a->op == OCONST && typev[a->type->etype]) {
|
||||
if(isbigendian)
|
||||
gpseudo(ADATA, s, nod32const(a->vconst>>32));
|
||||
else
|
||||
gpseudo(ADATA, s, nod32const(a->vconst));
|
||||
p->from.offset += o;
|
||||
p->reg = 4;
|
||||
if(isbigendian)
|
||||
gpseudo(ADATA, s, nod32const(a->vconst));
|
||||
else
|
||||
gpseudo(ADATA, s, nod32const(a->vconst>>32));
|
||||
p->from.offset += o + 4;
|
||||
p->reg = 4;
|
||||
return;
|
||||
}
|
||||
gpseudo(ADATA, s, a);
|
||||
p->from.offset += o;
|
||||
p->reg = w;
|
||||
if(p->to.type == D_OREG)
|
||||
p->to.type = D_CONST;
|
||||
}
|
||||
|
||||
void
|
||||
outcode(void)
|
||||
{
|
||||
Bprint(&outbuf, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion());
|
||||
if(pragcgobuf.to > pragcgobuf.start) {
|
||||
Bprint(&outbuf, "\n");
|
||||
Bprint(&outbuf, "$$ // exports\n\n");
|
||||
Bprint(&outbuf, "$$ // local types\n\n");
|
||||
Bprint(&outbuf, "$$ // cgo\n");
|
||||
Bprint(&outbuf, "%s", fmtstrflush(&pragcgobuf));
|
||||
Bprint(&outbuf, "\n$$\n\n");
|
||||
}
|
||||
Bprint(&outbuf, "!\n");
|
||||
|
||||
writeobj(ctxt, &outbuf);
|
||||
lastp = P;
|
||||
}
|
||||
|
||||
int32
|
||||
align(int32 i, Type *t, int op, int32 *maxalign)
|
||||
{
|
||||
int32 o;
|
||||
Type *v;
|
||||
int w, packw;
|
||||
|
||||
o = i;
|
||||
w = 1;
|
||||
packw = 0;
|
||||
switch(op) {
|
||||
default:
|
||||
diag(Z, "unknown align opcode %d", op);
|
||||
break;
|
||||
|
||||
case Asu2: /* padding at end of a struct */
|
||||
w = *maxalign;
|
||||
if(w < 1)
|
||||
w = 1;
|
||||
if(packflg)
|
||||
packw = packflg;
|
||||
break;
|
||||
|
||||
case Ael1: /* initial align of struct element */
|
||||
for(v=t; v->etype==TARRAY; v=v->link)
|
||||
;
|
||||
if(v->etype == TSTRUCT || v->etype == TUNION)
|
||||
w = v->align;
|
||||
else {
|
||||
w = ewidth[v->etype];
|
||||
if(w == 8)
|
||||
w = 4;
|
||||
}
|
||||
if(w < 1 || w > SZ_LONG)
|
||||
fatal(Z, "align");
|
||||
if(packflg)
|
||||
packw = packflg;
|
||||
break;
|
||||
|
||||
case Ael2: /* width of a struct element */
|
||||
o += t->width;
|
||||
break;
|
||||
|
||||
case Aarg0: /* initial passbyptr argument in arg list */
|
||||
if(typesuv[t->etype]) {
|
||||
o = align(o, types[TIND], Aarg1, nil);
|
||||
o = align(o, types[TIND], Aarg2, nil);
|
||||
}
|
||||
break;
|
||||
|
||||
case Aarg1: /* initial align of parameter */
|
||||
w = ewidth[t->etype];
|
||||
if(w <= 0 || w >= SZ_LONG) {
|
||||
w = SZ_LONG;
|
||||
break;
|
||||
}
|
||||
w = 1; /* little endian no adjustment */
|
||||
break;
|
||||
|
||||
case Aarg2: /* width of a parameter */
|
||||
o += t->width;
|
||||
w = t->width;
|
||||
if(w > SZ_LONG)
|
||||
w = SZ_LONG;
|
||||
break;
|
||||
|
||||
case Aaut3: /* total align of automatic */
|
||||
o = align(o, t, Ael2, nil);
|
||||
o = align(o, t, Ael1, nil);
|
||||
w = SZ_LONG; /* because of a pun in cc/dcl.c:contig() */
|
||||
break;
|
||||
}
|
||||
if(packw != 0 && xround(o, w) != xround(o, packw))
|
||||
diag(Z, "#pragma pack changes offset of %T", t);
|
||||
o = xround(o, w);
|
||||
if(maxalign != nil && *maxalign < w)
|
||||
*maxalign = w;
|
||||
if(debug['A'])
|
||||
print("align %s %d %T = %d\n", bnames[op], i, t, o);
|
||||
return o;
|
||||
}
|
||||
|
||||
int32
|
||||
maxround(int32 max, int32 v)
|
||||
{
|
||||
v = xround(v, SZ_LONG);
|
||||
if(v > max)
|
||||
return v;
|
||||
return max;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user