mirror of
https://github.com/golang/go.git
synced 2026-02-04 01:45:06 +03:00
Compare commits
100 Commits
dev.power6
...
go1.4.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
b3932baba4 | ||
|
|
6150414cb8 | ||
|
|
f9d56543f1 | ||
|
|
59439f8ea3 | ||
|
|
891abf9cc7 | ||
|
|
38ea0ae05f | ||
|
|
1a60ea1c01 | ||
|
|
de7d1c4094 | ||
|
|
04c7b68b4a | ||
|
|
40818cfe1c | ||
|
|
0f8cd1438d | ||
|
|
e522a477c2 | ||
|
|
63fe9efb90 | ||
|
|
cea69d6877 | ||
|
|
f666167572 | ||
|
|
c99616fc67 | ||
|
|
a697c4b439 | ||
|
|
2ad99f0960 | ||
|
|
2cd05c3404 | ||
|
|
9bc842ca18 | ||
|
|
af3e02e404 | ||
|
|
b53bdd496c | ||
|
|
9a571deed6 | ||
|
|
18b4f06b13 | ||
|
|
844889dfe2 | ||
|
|
7f0be1f781 | ||
|
|
68e2dbe8b7 | ||
|
|
03c008bcb2 | ||
|
|
cf105e2fa0 | ||
|
|
1340c6d593 | ||
|
|
ec7f33300f | ||
|
|
6bd0d0542e | ||
|
|
08b2cb4afe | ||
|
|
6bc812e9ec | ||
|
|
9b5444420c | ||
|
|
5b110c7b08 | ||
|
|
6ad16c4a48 | ||
|
|
1cdd9b407d | ||
|
|
23ecad07cd | ||
|
|
908dcab6f8 | ||
|
|
39bcbb353c | ||
|
|
2d0db8e591 | ||
|
|
67742ef560 | ||
|
|
590f528376 | ||
|
|
bb4a358af3 | ||
|
|
c6e53fea10 | ||
|
|
516d9ef53b | ||
|
|
182ec4395e | ||
|
|
489ff75ab8 |
10
.gitattributes
vendored
Normal file
10
.gitattributes
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Treat all files in the Go repo as binary, with no git magic updating
|
||||
# line endings. Windows users contributing to Go will need to use a
|
||||
# modern version of git and editors capable of LF line endings.
|
||||
#
|
||||
# We'll prevent accidental CRLF line endings from entering the repo
|
||||
# via the git-review gofmt checks.
|
||||
#
|
||||
# See golang.org/issue/9281
|
||||
|
||||
* -text
|
||||
53
.gitignore
vendored
Normal file
53
.gitignore
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
.DS_Store
|
||||
*.[5689ao]
|
||||
*.a[5689o]
|
||||
*.so
|
||||
*.pyc
|
||||
._*
|
||||
.nfs.*
|
||||
[5689a].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/zaexperiment.h
|
||||
src/runtime/zversion.go
|
||||
src/unicode/maketables
|
||||
src/*.*/
|
||||
test/pass.out
|
||||
test/run.out
|
||||
test/times.out
|
||||
test/garbage/*.out
|
||||
goinstall.log
|
||||
last-change
|
||||
VERSION.cache
|
||||
|
||||
bin/
|
||||
pkg/
|
||||
@@ -2,13 +2,13 @@ syntax:glob
|
||||
.DS_Store
|
||||
.git
|
||||
.gitignore
|
||||
*.[5689ao]
|
||||
*.a[5689o]
|
||||
*.[568ao]
|
||||
*.a[568o]
|
||||
*.so
|
||||
*.pyc
|
||||
._*
|
||||
.nfs.*
|
||||
[5689a].out
|
||||
[568a].out
|
||||
*~
|
||||
*.orig
|
||||
*.rej
|
||||
|
||||
2
AUTHORS
2
AUTHORS
@@ -145,7 +145,7 @@ Egon Elbre <egonelbre@gmail.com>
|
||||
Ehren Kret <ehren.kret@gmail.com>
|
||||
Eivind Uggedal <eivind@uggedal.com>
|
||||
Elias Naur <elias.naur@gmail.com>
|
||||
Emil Hessman <c.emil.hessman@gmail.com>
|
||||
Emil Hessman <c.emil.hessman@gmail.com> <emil@hessman.se>
|
||||
Eoghan Sherry <ejsherry@gmail.com>
|
||||
Eric Clark <zerohp@gmail.com>
|
||||
Eric Milliken <emilliken@gmail.com>
|
||||
|
||||
@@ -214,7 +214,7 @@ Egon Elbre <egonelbre@gmail.com>
|
||||
Ehren Kret <ehren.kret@gmail.com>
|
||||
Eivind Uggedal <eivind@uggedal.com>
|
||||
Elias Naur <elias.naur@gmail.com>
|
||||
Emil Hessman <c.emil.hessman@gmail.com>
|
||||
Emil Hessman <c.emil.hessman@gmail.com> <emil@hessman.se>
|
||||
Eoghan Sherry <ejsherry@gmail.com>
|
||||
Eric Clark <zerohp@gmail.com>
|
||||
Eric Milliken <emilliken@gmail.com>
|
||||
@@ -452,6 +452,7 @@ Nicholas Katsaros <nick@nickkatsaros.com>
|
||||
Nicholas Presta <nick@nickpresta.ca> <nick1presta@gmail.com>
|
||||
Nicholas Sullivan <nicholas.sullivan@gmail.com>
|
||||
Nicholas Waples <nwaples@gmail.com>
|
||||
Nick Cooper <nmvc@google.com>
|
||||
Nick Craig-Wood <nick@craig-wood.com> <nickcw@gmail.com>
|
||||
Nicolas Kaiser <nikai@nikai.net>
|
||||
Nicolas Owens <mischief@offblast.org>
|
||||
|
||||
604
api/go1.4.txt
Normal file
604
api/go1.4.txt
Normal file
@@ -0,0 +1,604 @@
|
||||
# CL 134210043 archive/zip: add Writer.Flush, Brad Fitzpatrick <bradfitz@golang.org>
|
||||
pkg archive/zip, method (*Writer) Flush() error
|
||||
|
||||
# CL 97140043 compress/flate: add Reset() to allow reusing large buffers to compress multiple buffers, James Robinson <jamesr@google.com>
|
||||
pkg compress/flate, type Resetter interface { Reset }
|
||||
pkg compress/flate, type Resetter interface, Reset(io.Reader, []uint8) error
|
||||
pkg compress/zlib, type Resetter interface { Reset }
|
||||
pkg compress/zlib, type Resetter interface, Reset(io.Reader, []uint8) error
|
||||
|
||||
# CL 159120044 compress/gzip: allow stopping at end of first stream, Russ Cox <rsc@golang.org>
|
||||
pkg compress/gzip, method (*Reader) Multistream(bool)
|
||||
|
||||
# CL 138800043 crypto: Add SHA3 functions in go.crypto/sha3 to the Hash enum., David Leon Gil <coruus@gmail.com>
|
||||
pkg crypto, const SHA3_224 = 10
|
||||
pkg crypto, const SHA3_224 Hash
|
||||
pkg crypto, const SHA3_256 = 11
|
||||
pkg crypto, const SHA3_256 Hash
|
||||
pkg crypto, const SHA3_384 = 12
|
||||
pkg crypto, const SHA3_384 Hash
|
||||
pkg crypto, const SHA3_512 = 13
|
||||
pkg crypto, const SHA3_512 Hash
|
||||
|
||||
# CL 114680043 crypto: add Signer, Adam Langley <agl@golang.org>
|
||||
pkg crypto, method (Hash) HashFunc() Hash
|
||||
pkg crypto, type Signer interface { Public, Sign }
|
||||
pkg crypto, type Signer interface, Public() PublicKey
|
||||
pkg crypto, type Signer interface, Sign(io.Reader, []uint8, SignerOpts) ([]uint8, error)
|
||||
pkg crypto, type SignerOpts interface { HashFunc }
|
||||
pkg crypto, type SignerOpts interface, HashFunc() Hash
|
||||
pkg crypto/ecdsa, method (*PrivateKey) Public() crypto.PublicKey
|
||||
pkg crypto/ecdsa, method (*PrivateKey) Sign(io.Reader, []uint8, crypto.SignerOpts) ([]uint8, error)
|
||||
pkg crypto/rsa, method (*PSSOptions) HashFunc() crypto.Hash
|
||||
pkg crypto/rsa, method (*PrivateKey) Public() crypto.PublicKey
|
||||
pkg crypto/rsa, method (*PrivateKey) Sign(io.Reader, []uint8, crypto.SignerOpts) ([]uint8, error)
|
||||
pkg crypto/rsa, type PSSOptions struct, Hash crypto.Hash
|
||||
|
||||
# CL 157090043 crypto/tls: support TLS_FALLBACK_SCSV as a server., Adam Langley <agl@golang.org>
|
||||
pkg crypto/tls, const TLS_FALLBACK_SCSV = 22016
|
||||
pkg crypto/tls, const TLS_FALLBACK_SCSV uint16
|
||||
|
||||
# CL 107400043 crypto/tls: Added dynamic alternative to NameToCertificate map for SNI, Percy Wegmann <ox.to.a.cart@gmail.com>
|
||||
pkg crypto/tls, type ClientHelloInfo struct
|
||||
pkg crypto/tls, type ClientHelloInfo struct, CipherSuites []uint16
|
||||
pkg crypto/tls, type ClientHelloInfo struct, ServerName string
|
||||
pkg crypto/tls, type ClientHelloInfo struct, SupportedCurves []CurveID
|
||||
pkg crypto/tls, type ClientHelloInfo struct, SupportedPoints []uint8
|
||||
pkg crypto/tls, type Config struct, GetCertificate func(*ClientHelloInfo) (*Certificate, error)
|
||||
pkg crypto/tls, type ConnectionState struct, TLSUnique []uint8
|
||||
|
||||
# CL 153420045 crypto/x509: continue to recognise MaxPathLen of zero as "no value"., Adam Langley <agl@golang.org>
|
||||
pkg crypto/x509, type Certificate struct, MaxPathLenZero bool
|
||||
|
||||
# CL 158950043 database/sql: add Drivers, returning list of registered drivers, Russ Cox <rsc@golang.org>
|
||||
pkg database/sql, func Drivers() []string
|
||||
|
||||
# CL 117280043 debug/dwarf: fix Reader panic on DW_TAG_unspecified_type, Derek Parker <parkerderek86@gmail.com>
|
||||
pkg debug/dwarf, method (*UnspecifiedType) Basic() *BasicType
|
||||
pkg debug/dwarf, method (*UnspecifiedType) Common() *CommonType
|
||||
pkg debug/dwarf, method (*UnspecifiedType) Size() int64
|
||||
pkg debug/dwarf, method (*UnspecifiedType) String() string
|
||||
pkg debug/dwarf, type UnspecifiedType struct
|
||||
pkg debug/dwarf, type UnspecifiedType struct, embedded BasicType
|
||||
|
||||
# CL 132000043 debug/elf: support arm64 relocations, Michael Hudson-Doyle <michael.hudson@linaro.org>
|
||||
pkg debug/elf, const EM_AARCH64 = 183
|
||||
pkg debug/elf, const EM_AARCH64 Machine
|
||||
pkg debug/elf, const R_AARCH64_ABS16 = 259
|
||||
pkg debug/elf, const R_AARCH64_ABS16 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_ABS32 = 258
|
||||
pkg debug/elf, const R_AARCH64_ABS32 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_ABS64 = 257
|
||||
pkg debug/elf, const R_AARCH64_ABS64 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_ADD_ABS_LO12_NC = 277
|
||||
pkg debug/elf, const R_AARCH64_ADD_ABS_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_ADR_GOT_PAGE = 311
|
||||
pkg debug/elf, const R_AARCH64_ADR_GOT_PAGE R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_ADR_PREL_LO21 = 274
|
||||
pkg debug/elf, const R_AARCH64_ADR_PREL_LO21 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_ADR_PREL_PG_HI21 = 275
|
||||
pkg debug/elf, const R_AARCH64_ADR_PREL_PG_HI21 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_ADR_PREL_PG_HI21_NC = 276
|
||||
pkg debug/elf, const R_AARCH64_ADR_PREL_PG_HI21_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_CALL26 = 283
|
||||
pkg debug/elf, const R_AARCH64_CALL26 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_CONDBR19 = 280
|
||||
pkg debug/elf, const R_AARCH64_CONDBR19 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_COPY = 1024
|
||||
pkg debug/elf, const R_AARCH64_COPY R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_GLOB_DAT = 1025
|
||||
pkg debug/elf, const R_AARCH64_GLOB_DAT R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_GOT_LD_PREL19 = 309
|
||||
pkg debug/elf, const R_AARCH64_GOT_LD_PREL19 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_IRELATIVE = 1032
|
||||
pkg debug/elf, const R_AARCH64_IRELATIVE R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_JUMP26 = 282
|
||||
pkg debug/elf, const R_AARCH64_JUMP26 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_JUMP_SLOT = 1026
|
||||
pkg debug/elf, const R_AARCH64_JUMP_SLOT R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_LD64_GOT_LO12_NC = 312
|
||||
pkg debug/elf, const R_AARCH64_LD64_GOT_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_LDST128_ABS_LO12_NC = 299
|
||||
pkg debug/elf, const R_AARCH64_LDST128_ABS_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_LDST16_ABS_LO12_NC = 284
|
||||
pkg debug/elf, const R_AARCH64_LDST16_ABS_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_LDST32_ABS_LO12_NC = 285
|
||||
pkg debug/elf, const R_AARCH64_LDST32_ABS_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_LDST64_ABS_LO12_NC = 286
|
||||
pkg debug/elf, const R_AARCH64_LDST64_ABS_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_LDST8_ABS_LO12_NC = 278
|
||||
pkg debug/elf, const R_AARCH64_LDST8_ABS_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_LD_PREL_LO19 = 273
|
||||
pkg debug/elf, const R_AARCH64_LD_PREL_LO19 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_MOVW_SABS_G0 = 270
|
||||
pkg debug/elf, const R_AARCH64_MOVW_SABS_G0 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_MOVW_SABS_G1 = 271
|
||||
pkg debug/elf, const R_AARCH64_MOVW_SABS_G1 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_MOVW_SABS_G2 = 272
|
||||
pkg debug/elf, const R_AARCH64_MOVW_SABS_G2 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_MOVW_UABS_G0 = 263
|
||||
pkg debug/elf, const R_AARCH64_MOVW_UABS_G0 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_MOVW_UABS_G0_NC = 264
|
||||
pkg debug/elf, const R_AARCH64_MOVW_UABS_G0_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_MOVW_UABS_G1 = 265
|
||||
pkg debug/elf, const R_AARCH64_MOVW_UABS_G1 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_MOVW_UABS_G1_NC = 266
|
||||
pkg debug/elf, const R_AARCH64_MOVW_UABS_G1_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_MOVW_UABS_G2 = 267
|
||||
pkg debug/elf, const R_AARCH64_MOVW_UABS_G2 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_MOVW_UABS_G2_NC = 268
|
||||
pkg debug/elf, const R_AARCH64_MOVW_UABS_G2_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_MOVW_UABS_G3 = 269
|
||||
pkg debug/elf, const R_AARCH64_MOVW_UABS_G3 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_NONE = 0
|
||||
pkg debug/elf, const R_AARCH64_NONE R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_NULL = 256
|
||||
pkg debug/elf, const R_AARCH64_NULL R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_ABS16 = 2
|
||||
pkg debug/elf, const R_AARCH64_P32_ABS16 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_ABS32 = 1
|
||||
pkg debug/elf, const R_AARCH64_P32_ABS32 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_ADD_ABS_LO12_NC = 12
|
||||
pkg debug/elf, const R_AARCH64_P32_ADD_ABS_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_ADR_GOT_PAGE = 26
|
||||
pkg debug/elf, const R_AARCH64_P32_ADR_GOT_PAGE R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_ADR_PREL_LO21 = 10
|
||||
pkg debug/elf, const R_AARCH64_P32_ADR_PREL_LO21 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_ADR_PREL_PG_HI21 = 11
|
||||
pkg debug/elf, const R_AARCH64_P32_ADR_PREL_PG_HI21 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_CALL26 = 21
|
||||
pkg debug/elf, const R_AARCH64_P32_CALL26 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_CONDBR19 = 19
|
||||
pkg debug/elf, const R_AARCH64_P32_CONDBR19 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_COPY = 180
|
||||
pkg debug/elf, const R_AARCH64_P32_COPY R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_GLOB_DAT = 181
|
||||
pkg debug/elf, const R_AARCH64_P32_GLOB_DAT R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_GOT_LD_PREL19 = 25
|
||||
pkg debug/elf, const R_AARCH64_P32_GOT_LD_PREL19 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_IRELATIVE = 188
|
||||
pkg debug/elf, const R_AARCH64_P32_IRELATIVE R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_JUMP26 = 20
|
||||
pkg debug/elf, const R_AARCH64_P32_JUMP26 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_JUMP_SLOT = 182
|
||||
pkg debug/elf, const R_AARCH64_P32_JUMP_SLOT R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_LD32_GOT_LO12_NC = 27
|
||||
pkg debug/elf, const R_AARCH64_P32_LD32_GOT_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_LDST128_ABS_LO12_NC = 17
|
||||
pkg debug/elf, const R_AARCH64_P32_LDST128_ABS_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_LDST16_ABS_LO12_NC = 14
|
||||
pkg debug/elf, const R_AARCH64_P32_LDST16_ABS_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_LDST32_ABS_LO12_NC = 15
|
||||
pkg debug/elf, const R_AARCH64_P32_LDST32_ABS_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_LDST64_ABS_LO12_NC = 16
|
||||
pkg debug/elf, const R_AARCH64_P32_LDST64_ABS_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_LDST8_ABS_LO12_NC = 13
|
||||
pkg debug/elf, const R_AARCH64_P32_LDST8_ABS_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_LD_PREL_LO19 = 9
|
||||
pkg debug/elf, const R_AARCH64_P32_LD_PREL_LO19 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_MOVW_SABS_G0 = 8
|
||||
pkg debug/elf, const R_AARCH64_P32_MOVW_SABS_G0 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_MOVW_UABS_G0 = 5
|
||||
pkg debug/elf, const R_AARCH64_P32_MOVW_UABS_G0 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_MOVW_UABS_G0_NC = 6
|
||||
pkg debug/elf, const R_AARCH64_P32_MOVW_UABS_G0_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_MOVW_UABS_G1 = 7
|
||||
pkg debug/elf, const R_AARCH64_P32_MOVW_UABS_G1 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_PREL16 = 4
|
||||
pkg debug/elf, const R_AARCH64_P32_PREL16 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_PREL32 = 3
|
||||
pkg debug/elf, const R_AARCH64_P32_PREL32 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_RELATIVE = 183
|
||||
pkg debug/elf, const R_AARCH64_P32_RELATIVE R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSDESC = 187
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSDESC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSDESC_ADD_LO12_NC = 126
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSDESC_ADD_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSDESC_ADR_PAGE21 = 124
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSDESC_ADR_PAGE21 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSDESC_ADR_PREL21 = 123
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSDESC_ADR_PREL21 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSDESC_CALL = 127
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSDESC_CALL R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSDESC_LD32_LO12_NC = 125
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSDESC_LD32_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSDESC_LD_PREL19 = 122
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSDESC_LD_PREL19 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSGD_ADD_LO12_NC = 82
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSGD_ADD_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSGD_ADR_PAGE21 = 81
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSGD_ADR_PAGE21 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21 = 103
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC = 104
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19 = 105
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSLE_ADD_TPREL_HI12 = 109
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSLE_ADD_TPREL_HI12 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSLE_ADD_TPREL_LO12 = 110
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSLE_ADD_TPREL_LO12 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC = 111
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSLE_MOVW_TPREL_G0 = 107
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSLE_MOVW_TPREL_G0 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC = 108
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSLE_MOVW_TPREL_G1 = 106
|
||||
pkg debug/elf, const R_AARCH64_P32_TLSLE_MOVW_TPREL_G1 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLS_DTPMOD = 184
|
||||
pkg debug/elf, const R_AARCH64_P32_TLS_DTPMOD R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLS_DTPREL = 185
|
||||
pkg debug/elf, const R_AARCH64_P32_TLS_DTPREL R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TLS_TPREL = 186
|
||||
pkg debug/elf, const R_AARCH64_P32_TLS_TPREL R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_P32_TSTBR14 = 18
|
||||
pkg debug/elf, const R_AARCH64_P32_TSTBR14 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_PREL16 = 262
|
||||
pkg debug/elf, const R_AARCH64_PREL16 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_PREL32 = 261
|
||||
pkg debug/elf, const R_AARCH64_PREL32 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_PREL64 = 260
|
||||
pkg debug/elf, const R_AARCH64_PREL64 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_RELATIVE = 1027
|
||||
pkg debug/elf, const R_AARCH64_RELATIVE R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC = 1031
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_ADD = 568
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_ADD R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_ADD_LO12_NC = 564
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_ADD_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_ADR_PAGE21 = 562
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_ADR_PAGE21 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_ADR_PREL21 = 561
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_ADR_PREL21 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_CALL = 569
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_CALL R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_LD64_LO12_NC = 563
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_LD64_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_LDR = 567
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_LDR R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_LD_PREL19 = 560
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_LD_PREL19 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_OFF_G0_NC = 566
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_OFF_G0_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_OFF_G1 = 565
|
||||
pkg debug/elf, const R_AARCH64_TLSDESC_OFF_G1 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSGD_ADD_LO12_NC = 514
|
||||
pkg debug/elf, const R_AARCH64_TLSGD_ADD_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSGD_ADR_PAGE21 = 513
|
||||
pkg debug/elf, const R_AARCH64_TLSGD_ADR_PAGE21 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 = 541
|
||||
pkg debug/elf, const R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC = 542
|
||||
pkg debug/elf, const R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 = 543
|
||||
pkg debug/elf, const R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC = 540
|
||||
pkg debug/elf, const R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 = 539
|
||||
pkg debug/elf, const R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSLE_ADD_TPREL_HI12 = 549
|
||||
pkg debug/elf, const R_AARCH64_TLSLE_ADD_TPREL_HI12 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSLE_ADD_TPREL_LO12 = 550
|
||||
pkg debug/elf, const R_AARCH64_TLSLE_ADD_TPREL_LO12 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSLE_ADD_TPREL_LO12_NC = 551
|
||||
pkg debug/elf, const R_AARCH64_TLSLE_ADD_TPREL_LO12_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G0 = 547
|
||||
pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G0 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G0_NC = 548
|
||||
pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G0_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G1 = 545
|
||||
pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G1 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G1_NC = 546
|
||||
pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G1_NC R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G2 = 544
|
||||
pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G2 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLS_DTPMOD64 = 1028
|
||||
pkg debug/elf, const R_AARCH64_TLS_DTPMOD64 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLS_DTPREL64 = 1029
|
||||
pkg debug/elf, const R_AARCH64_TLS_DTPREL64 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TLS_TPREL64 = 1030
|
||||
pkg debug/elf, const R_AARCH64_TLS_TPREL64 R_AARCH64
|
||||
pkg debug/elf, const R_AARCH64_TSTBR14 = 279
|
||||
pkg debug/elf, const R_AARCH64_TSTBR14 R_AARCH64
|
||||
pkg debug/elf, method (R_AARCH64) GoString() string
|
||||
pkg debug/elf, method (R_AARCH64) String() string
|
||||
pkg debug/elf, type R_AARCH64 int
|
||||
|
||||
# CL 107530043 debug/elf: add (*File).DynamicSymbols, ErrNoSymbols, and tests for (*File).Symbols and (*File).DynamicSymbols, and formalize symbol order., Pietro Gagliardi <pietro10@mac.com>
|
||||
pkg debug/elf, method (*File) DynamicSymbols() ([]Symbol, error)
|
||||
pkg debug/elf, var ErrNoSymbols error
|
||||
|
||||
# CL 106460044 debug/plan9obj, cmd/addr2line: on Plan 9 use a.out header, Aram Hăvărneanu <aram@mgk.ro>
|
||||
pkg debug/plan9obj, type FileHeader struct, HdrSize uint64
|
||||
pkg debug/plan9obj, type FileHeader struct, LoadAddress uint64
|
||||
|
||||
# CL 122960043 encoding/xml: add InputOffset method to Decoder, Russ Cox <rsc@golang.org>
|
||||
pkg encoding/xml, method (*Decoder) InputOffset() int64
|
||||
|
||||
# CL 124940043 cmd/go, go/build: implement import comment checking, Russ Cox <rsc@golang.org>
|
||||
pkg go/build, const ImportComment = 4
|
||||
pkg go/build, const ImportComment ImportMode
|
||||
pkg go/build, type Package struct, ImportComment string
|
||||
|
||||
# CL 155050043 go/build: Return MultiplePackageError on importing a dir containing multiple packages, Jens Frederich <jfrederich@gmail.com>
|
||||
pkg go/build, method (*MultiplePackageError) Error() string
|
||||
pkg go/build, type MultiplePackageError struct
|
||||
pkg go/build, type MultiplePackageError struct, Dir string
|
||||
pkg go/build, type MultiplePackageError struct, Files []string
|
||||
pkg go/build, type MultiplePackageError struct, Packages []string
|
||||
|
||||
# CL 135110044 go/token: implement PositionFor accessors, Robert Griesemer <gri@golang.org>
|
||||
pkg go/token, method (*File) PositionFor(Pos, bool) Position
|
||||
pkg go/token, method (*FileSet) PositionFor(Pos, bool) Position
|
||||
|
||||
# CL 109000049 image: add RGBAAt, Gray16At, etc., ChaiShushan <chaishushan@gmail.com>
|
||||
pkg image, method (*Alpha) AlphaAt(int, int) color.Alpha
|
||||
pkg image, method (*Alpha16) Alpha16At(int, int) color.Alpha16
|
||||
pkg image, method (*Gray) GrayAt(int, int) color.Gray
|
||||
pkg image, method (*Gray16) Gray16At(int, int) color.Gray16
|
||||
pkg image, method (*NRGBA) NRGBAAt(int, int) color.NRGBA
|
||||
pkg image, method (*NRGBA64) NRGBA64At(int, int) color.NRGBA64
|
||||
pkg image, method (*RGBA) RGBAAt(int, int) color.RGBA
|
||||
pkg image, method (*RGBA64) RGBA64At(int, int) color.RGBA64
|
||||
pkg image, method (*YCbCr) YCbCrAt(int, int) color.YCbCr
|
||||
|
||||
# CL 129190043 png: make the encoder configurable, Jeff R. Allen <jra@nella.org>
|
||||
pkg image/png, const BestCompression = -3
|
||||
pkg image/png, const BestCompression CompressionLevel
|
||||
pkg image/png, const BestSpeed = -2
|
||||
pkg image/png, const BestSpeed CompressionLevel
|
||||
pkg image/png, const DefaultCompression = 0
|
||||
pkg image/png, const DefaultCompression CompressionLevel
|
||||
pkg image/png, const NoCompression = -1
|
||||
pkg image/png, const NoCompression CompressionLevel
|
||||
pkg image/png, method (*Encoder) Encode(io.Writer, image.Image) error
|
||||
pkg image/png, type CompressionLevel int
|
||||
pkg image/png, type Encoder struct
|
||||
pkg image/png, type Encoder struct, CompressionLevel CompressionLevel
|
||||
|
||||
# CL 101750048 math: implement Nextafter32, Robert Griesemer <gri@golang.org>
|
||||
pkg math, func Nextafter32(float32, float32) float32
|
||||
|
||||
# CL 93550043 math/big: implement Rat.Float32, Robert Griesemer <gri@golang.org>
|
||||
pkg math/big, method (*Rat) Float32() (float32, bool)
|
||||
|
||||
# CL 76540043 net/http: add BasicAuth method to *http.Request, Kelsey Hightower <kelsey.hightower@gmail.com>
|
||||
pkg net/http, method (*Request) BasicAuth() (string, string, bool)
|
||||
|
||||
# CL 137940043 net/http: add Transport.DialTLS hook, Brad Fitzpatrick <bradfitz@golang.org>
|
||||
pkg net/http, type Transport struct, DialTLS func(string, string) (net.Conn, error)
|
||||
|
||||
# CL 132750043 net/http/httputil: Pass a Logger to ReverseProxy, allowing the user to control logging., Mark Theunissen <mark.theunissen@gmail.com>
|
||||
pkg net/http/httputil, type ReverseProxy struct, ErrorLog *log.Logger
|
||||
|
||||
# CL 148370043 os, syscall: add Unsetenv, Brad Fitzpatrick <bradfitz@golang.org>
|
||||
pkg os, func Unsetenv(string) error
|
||||
pkg syscall, func Unsetenv(string) error
|
||||
|
||||
# CL 144020043 reflect: add Type.Comparable, Russ Cox <rsc@golang.org>
|
||||
pkg reflect, type Type interface, Comparable() bool
|
||||
|
||||
# CL 153670043 runtime: add PauseEnd array to MemStats and GCStats, Jens Frederich <jfrederich@gmail.com>
|
||||
pkg runtime, type MemStats struct, PauseEnd [256]uint64
|
||||
pkg runtime/debug, type GCStats struct, PauseEnd []time.Time
|
||||
|
||||
# CL 136710045 sync/atomic: add Value, Dmitriy Vyukov <dvyukov@google.com>
|
||||
pkg sync/atomic, method (*Value) Load() interface{}
|
||||
pkg sync/atomic, method (*Value) Store(interface{})
|
||||
pkg sync/atomic, type Value struct
|
||||
|
||||
# CL 126190043 syscall: support UID/GID map files for Linux user namespaces, Mrunal Patel <mrunalp@gmail.com>
|
||||
pkg syscall (linux-386), type SysProcAttr struct, GidMappings []SysProcIDMap
|
||||
pkg syscall (linux-386), type SysProcAttr struct, UidMappings []SysProcIDMap
|
||||
pkg syscall (linux-386), type SysProcIDMap struct
|
||||
pkg syscall (linux-386), type SysProcIDMap struct, ContainerID int
|
||||
pkg syscall (linux-386), type SysProcIDMap struct, HostID int
|
||||
pkg syscall (linux-386), type SysProcIDMap struct, Size int
|
||||
pkg syscall (linux-386-cgo), type SysProcAttr struct, GidMappings []SysProcIDMap
|
||||
pkg syscall (linux-386-cgo), type SysProcAttr struct, UidMappings []SysProcIDMap
|
||||
pkg syscall (linux-386-cgo), type SysProcIDMap struct
|
||||
pkg syscall (linux-386-cgo), type SysProcIDMap struct, ContainerID int
|
||||
pkg syscall (linux-386-cgo), type SysProcIDMap struct, HostID int
|
||||
pkg syscall (linux-386-cgo), type SysProcIDMap struct, Size int
|
||||
pkg syscall (linux-amd64), type SysProcAttr struct, GidMappings []SysProcIDMap
|
||||
pkg syscall (linux-amd64), type SysProcAttr struct, UidMappings []SysProcIDMap
|
||||
pkg syscall (linux-amd64), type SysProcIDMap struct
|
||||
pkg syscall (linux-amd64), type SysProcIDMap struct, ContainerID int
|
||||
pkg syscall (linux-amd64), type SysProcIDMap struct, HostID int
|
||||
pkg syscall (linux-amd64), type SysProcIDMap struct, Size int
|
||||
pkg syscall (linux-amd64-cgo), type SysProcAttr struct, GidMappings []SysProcIDMap
|
||||
pkg syscall (linux-amd64-cgo), type SysProcAttr struct, UidMappings []SysProcIDMap
|
||||
pkg syscall (linux-amd64-cgo), type SysProcIDMap struct
|
||||
pkg syscall (linux-amd64-cgo), type SysProcIDMap struct, ContainerID int
|
||||
pkg syscall (linux-amd64-cgo), type SysProcIDMap struct, HostID int
|
||||
pkg syscall (linux-amd64-cgo), type SysProcIDMap struct, Size int
|
||||
pkg syscall (linux-arm), type SysProcAttr struct, GidMappings []SysProcIDMap
|
||||
pkg syscall (linux-arm), type SysProcAttr struct, UidMappings []SysProcIDMap
|
||||
pkg syscall (linux-arm), type SysProcIDMap struct
|
||||
pkg syscall (linux-arm), type SysProcIDMap struct, ContainerID int
|
||||
pkg syscall (linux-arm), type SysProcIDMap struct, HostID int
|
||||
pkg syscall (linux-arm), type SysProcIDMap struct, Size int
|
||||
pkg syscall (linux-arm-cgo), type SysProcAttr struct, GidMappings []SysProcIDMap
|
||||
pkg syscall (linux-arm-cgo), type SysProcAttr struct, UidMappings []SysProcIDMap
|
||||
pkg syscall (linux-arm-cgo), type SysProcIDMap struct
|
||||
pkg syscall (linux-arm-cgo), type SysProcIDMap struct, ContainerID int
|
||||
pkg syscall (linux-arm-cgo), type SysProcIDMap struct, HostID int
|
||||
pkg syscall (linux-arm-cgo), type SysProcIDMap struct, Size int
|
||||
|
||||
# CL 122200043 net: fix CNAME resolving on Windows, Egon Elbre <egonelbre@gmail.com>
|
||||
pkg syscall (windows-386), const DNS_INFO_NO_RECORDS = 9501
|
||||
pkg syscall (windows-386), const DNS_INFO_NO_RECORDS ideal-int
|
||||
pkg syscall (windows-386), const DnsSectionAdditional = 3
|
||||
pkg syscall (windows-386), const DnsSectionAdditional ideal-int
|
||||
pkg syscall (windows-386), const DnsSectionAnswer = 1
|
||||
pkg syscall (windows-386), const DnsSectionAnswer ideal-int
|
||||
pkg syscall (windows-386), const DnsSectionAuthority = 2
|
||||
pkg syscall (windows-386), const DnsSectionAuthority ideal-int
|
||||
pkg syscall (windows-386), const DnsSectionQuestion = 0
|
||||
pkg syscall (windows-386), const DnsSectionQuestion ideal-int
|
||||
pkg syscall (windows-386), func DnsNameCompare(*uint16, *uint16) bool
|
||||
pkg syscall (windows-amd64), const DNS_INFO_NO_RECORDS = 9501
|
||||
pkg syscall (windows-amd64), const DNS_INFO_NO_RECORDS ideal-int
|
||||
pkg syscall (windows-amd64), const DnsSectionAdditional = 3
|
||||
pkg syscall (windows-amd64), const DnsSectionAdditional ideal-int
|
||||
pkg syscall (windows-amd64), const DnsSectionAnswer = 1
|
||||
pkg syscall (windows-amd64), const DnsSectionAnswer ideal-int
|
||||
pkg syscall (windows-amd64), const DnsSectionAuthority = 2
|
||||
pkg syscall (windows-amd64), const DnsSectionAuthority ideal-int
|
||||
pkg syscall (windows-amd64), const DnsSectionQuestion = 0
|
||||
pkg syscall (windows-amd64), const DnsSectionQuestion ideal-int
|
||||
pkg syscall (windows-amd64), func DnsNameCompare(*uint16, *uint16) bool
|
||||
|
||||
# CL 86160044 os: Implement symlink support for Windows, Michael Fraenkel <michael.fraenkel@gmail.com>
|
||||
pkg syscall (windows-386), const ERROR_PRIVILEGE_NOT_HELD = 1314
|
||||
pkg syscall (windows-386), const ERROR_PRIVILEGE_NOT_HELD Errno
|
||||
pkg syscall (windows-amd64), const ERROR_PRIVILEGE_NOT_HELD = 1314
|
||||
pkg syscall (windows-amd64), const ERROR_PRIVILEGE_NOT_HELD Errno
|
||||
|
||||
# CL 86160044 os: Implement symlink support for Windows, Michael Fraenkel <michael.fraenkel@gmail.com>
|
||||
pkg syscall (windows-386), const FILE_ATTRIBUTE_REPARSE_POINT = 1024
|
||||
pkg syscall (windows-386), const FILE_ATTRIBUTE_REPARSE_POINT ideal-int
|
||||
pkg syscall (windows-386), const FILE_FLAG_OPEN_REPARSE_POINT = 2097152
|
||||
pkg syscall (windows-386), const FILE_FLAG_OPEN_REPARSE_POINT ideal-int
|
||||
pkg syscall (windows-386), const FSCTL_GET_REPARSE_POINT = 589992
|
||||
pkg syscall (windows-386), const FSCTL_GET_REPARSE_POINT ideal-int
|
||||
pkg syscall (windows-386), const IO_REPARSE_TAG_SYMLINK = 2684354572
|
||||
pkg syscall (windows-386), const IO_REPARSE_TAG_SYMLINK ideal-int
|
||||
pkg syscall (windows-386), const MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16384
|
||||
pkg syscall (windows-386), const MAXIMUM_REPARSE_DATA_BUFFER_SIZE ideal-int
|
||||
pkg syscall (windows-386), const SYMBOLIC_LINK_FLAG_DIRECTORY = 1
|
||||
pkg syscall (windows-386), const SYMBOLIC_LINK_FLAG_DIRECTORY ideal-int
|
||||
pkg syscall (windows-386), func CreateHardLink(*uint16, *uint16, uintptr) error
|
||||
pkg syscall (windows-386), func CreateSymbolicLink(*uint16, *uint16, uint32) error
|
||||
pkg syscall (windows-386), func DeviceIoControl(Handle, uint32, *uint8, uint32, *uint8, uint32, *uint32, *Overlapped) error
|
||||
pkg syscall (windows-386), func LoadCreateSymbolicLink() error
|
||||
pkg syscall (windows-amd64), const FILE_ATTRIBUTE_REPARSE_POINT = 1024
|
||||
pkg syscall (windows-amd64), const FILE_ATTRIBUTE_REPARSE_POINT ideal-int
|
||||
pkg syscall (windows-amd64), const FILE_FLAG_OPEN_REPARSE_POINT = 2097152
|
||||
pkg syscall (windows-amd64), const FILE_FLAG_OPEN_REPARSE_POINT ideal-int
|
||||
pkg syscall (windows-amd64), const FSCTL_GET_REPARSE_POINT = 589992
|
||||
pkg syscall (windows-amd64), const FSCTL_GET_REPARSE_POINT ideal-int
|
||||
pkg syscall (windows-amd64), const IO_REPARSE_TAG_SYMLINK = 2684354572
|
||||
pkg syscall (windows-amd64), const IO_REPARSE_TAG_SYMLINK ideal-int
|
||||
pkg syscall (windows-amd64), const MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16384
|
||||
pkg syscall (windows-amd64), const MAXIMUM_REPARSE_DATA_BUFFER_SIZE ideal-int
|
||||
pkg syscall (windows-amd64), const SYMBOLIC_LINK_FLAG_DIRECTORY = 1
|
||||
pkg syscall (windows-amd64), const SYMBOLIC_LINK_FLAG_DIRECTORY ideal-int
|
||||
pkg syscall (windows-amd64), func CreateHardLink(*uint16, *uint16, uintptr) error
|
||||
pkg syscall (windows-amd64), func CreateSymbolicLink(*uint16, *uint16, uint32) error
|
||||
pkg syscall (windows-amd64), func DeviceIoControl(Handle, uint32, *uint8, uint32, *uint8, uint32, *uint32, *Overlapped) error
|
||||
pkg syscall (windows-amd64), func LoadCreateSymbolicLink() error
|
||||
|
||||
# CL 149510043 net: disable SIO_UDP_CONNRESET behavior on windows., Ron Hashimoto <mail@h2so5.net>
|
||||
pkg syscall (windows-386), const SIO_UDP_CONNRESET = 2550136844
|
||||
pkg syscall (windows-386), const SIO_UDP_CONNRESET ideal-int
|
||||
pkg syscall (windows-amd64), const SIO_UDP_CONNRESET = 2550136844
|
||||
pkg syscall (windows-amd64), const SIO_UDP_CONNRESET ideal-int
|
||||
|
||||
# CL 102320044 syscall: implement syscall.Getppid() on Windows, Alan Shreve <alan@inconshreveable.com>
|
||||
pkg syscall (windows-386), const TH32CS_INHERIT = 2147483648
|
||||
pkg syscall (windows-386), const TH32CS_INHERIT ideal-int
|
||||
pkg syscall (windows-386), const TH32CS_SNAPALL = 15
|
||||
pkg syscall (windows-386), const TH32CS_SNAPALL ideal-int
|
||||
pkg syscall (windows-386), const TH32CS_SNAPHEAPLIST = 1
|
||||
pkg syscall (windows-386), const TH32CS_SNAPHEAPLIST ideal-int
|
||||
pkg syscall (windows-386), const TH32CS_SNAPMODULE = 8
|
||||
pkg syscall (windows-386), const TH32CS_SNAPMODULE ideal-int
|
||||
pkg syscall (windows-386), const TH32CS_SNAPMODULE32 = 16
|
||||
pkg syscall (windows-386), const TH32CS_SNAPMODULE32 ideal-int
|
||||
pkg syscall (windows-386), const TH32CS_SNAPPROCESS = 2
|
||||
pkg syscall (windows-386), const TH32CS_SNAPPROCESS ideal-int
|
||||
pkg syscall (windows-386), const TH32CS_SNAPTHREAD = 4
|
||||
pkg syscall (windows-386), const TH32CS_SNAPTHREAD ideal-int
|
||||
pkg syscall (windows-386), func CreateToolhelp32Snapshot(uint32, uint32) (Handle, error)
|
||||
pkg syscall (windows-386), func Process32First(Handle, *ProcessEntry32) error
|
||||
pkg syscall (windows-386), func Process32Next(Handle, *ProcessEntry32) error
|
||||
pkg syscall (windows-386), type ProcessEntry32 struct
|
||||
pkg syscall (windows-386), type ProcessEntry32 struct, DefaultHeapID uintptr
|
||||
pkg syscall (windows-386), type ProcessEntry32 struct, ExeFile [260]uint16
|
||||
pkg syscall (windows-386), type ProcessEntry32 struct, Flags uint32
|
||||
pkg syscall (windows-386), type ProcessEntry32 struct, ModuleID uint32
|
||||
pkg syscall (windows-386), type ProcessEntry32 struct, ParentProcessID uint32
|
||||
pkg syscall (windows-386), type ProcessEntry32 struct, PriClassBase int32
|
||||
pkg syscall (windows-386), type ProcessEntry32 struct, ProcessID uint32
|
||||
pkg syscall (windows-386), type ProcessEntry32 struct, Size uint32
|
||||
pkg syscall (windows-386), type ProcessEntry32 struct, Threads uint32
|
||||
pkg syscall (windows-386), type ProcessEntry32 struct, Usage uint32
|
||||
pkg syscall (windows-amd64), const TH32CS_INHERIT = 2147483648
|
||||
pkg syscall (windows-amd64), const TH32CS_INHERIT ideal-int
|
||||
pkg syscall (windows-amd64), const TH32CS_SNAPALL = 15
|
||||
pkg syscall (windows-amd64), const TH32CS_SNAPALL ideal-int
|
||||
pkg syscall (windows-amd64), const TH32CS_SNAPHEAPLIST = 1
|
||||
pkg syscall (windows-amd64), const TH32CS_SNAPHEAPLIST ideal-int
|
||||
pkg syscall (windows-amd64), const TH32CS_SNAPMODULE = 8
|
||||
pkg syscall (windows-amd64), const TH32CS_SNAPMODULE ideal-int
|
||||
pkg syscall (windows-amd64), const TH32CS_SNAPMODULE32 = 16
|
||||
pkg syscall (windows-amd64), const TH32CS_SNAPMODULE32 ideal-int
|
||||
pkg syscall (windows-amd64), const TH32CS_SNAPPROCESS = 2
|
||||
pkg syscall (windows-amd64), const TH32CS_SNAPPROCESS ideal-int
|
||||
pkg syscall (windows-amd64), const TH32CS_SNAPTHREAD = 4
|
||||
pkg syscall (windows-amd64), const TH32CS_SNAPTHREAD ideal-int
|
||||
pkg syscall (windows-amd64), func CreateToolhelp32Snapshot(uint32, uint32) (Handle, error)
|
||||
pkg syscall (windows-amd64), func Process32First(Handle, *ProcessEntry32) error
|
||||
pkg syscall (windows-amd64), func Process32Next(Handle, *ProcessEntry32) error
|
||||
pkg syscall (windows-amd64), type ProcessEntry32 struct
|
||||
pkg syscall (windows-amd64), type ProcessEntry32 struct, DefaultHeapID uintptr
|
||||
pkg syscall (windows-amd64), type ProcessEntry32 struct, ExeFile [260]uint16
|
||||
pkg syscall (windows-amd64), type ProcessEntry32 struct, Flags uint32
|
||||
pkg syscall (windows-amd64), type ProcessEntry32 struct, ModuleID uint32
|
||||
pkg syscall (windows-amd64), type ProcessEntry32 struct, ParentProcessID uint32
|
||||
pkg syscall (windows-amd64), type ProcessEntry32 struct, PriClassBase int32
|
||||
pkg syscall (windows-amd64), type ProcessEntry32 struct, ProcessID uint32
|
||||
pkg syscall (windows-amd64), type ProcessEntry32 struct, Size uint32
|
||||
pkg syscall (windows-amd64), type ProcessEntry32 struct, Threads uint32
|
||||
pkg syscall (windows-amd64), type ProcessEntry32 struct, Usage uint32
|
||||
|
||||
# CL 127740043 os: make SameFile handle paths like c:a.txt properly, Alex Brainman <alex.brainman@gmail.com>
|
||||
pkg syscall (windows-386), func FullPath(string) (string, error)
|
||||
pkg syscall (windows-amd64), func FullPath(string) (string, error)
|
||||
|
||||
# CL 98150043 testing: add Coverage function, Russ Cox <rsc@golang.org>
|
||||
pkg testing, func Coverage() float64
|
||||
|
||||
# CL 148770043 cmd/go, testing: add TestMain support, Russ Cox <rsc@golang.org>
|
||||
pkg testing, func MainStart(func(string, string) (bool, error), []InternalTest, []InternalBenchmark, []InternalExample) *M
|
||||
pkg testing, method (*M) Run() int
|
||||
pkg testing, type M struct
|
||||
|
||||
# CL 108030044 text/scanner: provide facility for custom identifiers, Robert Griesemer <gri@golang.org>
|
||||
pkg text/scanner, type Scanner struct, IsIdentRune func(int32, int) bool
|
||||
|
||||
# CL 130620043 text/template: add back pointer to Nodes for better error generation, Rob Pike <r@golang.org>
|
||||
pkg text/template/parse, type DotNode struct, embedded NodeType
|
||||
pkg text/template/parse, type NilNode struct, embedded NodeType
|
||||
pkg text/template/parse, method (*BranchNode) Copy() Node
|
||||
pkg text/template/parse, method (*IdentifierNode) SetTree(*Tree) *IdentifierNode
|
||||
pkg html/template, type Error struct, Node parse.Node
|
||||
|
||||
# CL 127470043 unicode: strconv: regexp: Upgrade to Unicode 7.0.0., Marcel van Lohuizen <mpvl@golang.org>
|
||||
pkg unicode, const Version = "7.0.0"
|
||||
pkg unicode, var Bassa_Vah *RangeTable
|
||||
pkg unicode, var Caucasian_Albanian *RangeTable
|
||||
pkg unicode, var Duployan *RangeTable
|
||||
pkg unicode, var Elbasan *RangeTable
|
||||
pkg unicode, var Grantha *RangeTable
|
||||
pkg unicode, var Khojki *RangeTable
|
||||
pkg unicode, var Khudawadi *RangeTable
|
||||
pkg unicode, var Linear_A *RangeTable
|
||||
pkg unicode, var Mahajani *RangeTable
|
||||
pkg unicode, var Manichaean *RangeTable
|
||||
pkg unicode, var Mende_Kikakui *RangeTable
|
||||
pkg unicode, var Modi *RangeTable
|
||||
pkg unicode, var Mro *RangeTable
|
||||
pkg unicode, var Nabataean *RangeTable
|
||||
pkg unicode, var Old_North_Arabian *RangeTable
|
||||
pkg unicode, var Old_Permic *RangeTable
|
||||
pkg unicode, var Pahawh_Hmong *RangeTable
|
||||
pkg unicode, var Palmyrene *RangeTable
|
||||
pkg unicode, var Pau_Cin_Hau *RangeTable
|
||||
pkg unicode, var Psalter_Pahlavi *RangeTable
|
||||
pkg unicode, var Siddham *RangeTable
|
||||
pkg unicode, var Tirhuta *RangeTable
|
||||
pkg unicode, var Warang_Citi *RangeTable
|
||||
@@ -78,17 +78,18 @@ well-established conventions.</p>
|
||||
source code. For Bitbucket, GitHub, Google Code, and Launchpad, the
|
||||
root directory of the repository is identified by the repository's
|
||||
main URL, without the <code>http://</code> prefix. Subdirectories are named by
|
||||
adding to that path. For example, the supplemental networking
|
||||
libraries for Go are obtained by running</p>
|
||||
adding to that path.
|
||||
For example, the Go example programs are obtained by running</p>
|
||||
|
||||
<pre>
|
||||
hg clone http://code.google.com/p/go.net
|
||||
git clone https://github.com/golang/example
|
||||
</pre>
|
||||
|
||||
<p>and thus the import path for the root directory of that repository is
|
||||
"<code>code.google.com/p/go.net</code>". The websocket package is stored in a
|
||||
subdirectory, so its import path is
|
||||
"<code>code.google.com/p/go.net/websocket</code>".</p>
|
||||
"<code>github.com/golang/example</code>".
|
||||
The <a href="https://godoc.org/github.com/golang/example/stringutil">stringutil</a>
|
||||
package is stored in a subdirectory, so its import path is
|
||||
"<code>github.com/golang/example/stringutil</code>".</p>
|
||||
|
||||
<p>These paths are on the long side, but in exchange we get an
|
||||
automatically managed name space for import paths and the ability for
|
||||
|
||||
@@ -62,7 +62,7 @@ details.
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><a href="//godoc.org/code.google.com/p/go.tools/cmd/cover/">cover</a></td>
|
||||
<td><a href="//godoc.org/golang.org/x/tools/cmd/cover/">cover</a></td>
|
||||
<td> </td>
|
||||
<td>Cover is a program for creating and analyzing the coverage profiles
|
||||
generated by <code>"go test -coverprofile"</code>.</td>
|
||||
@@ -83,13 +83,13 @@ gofmt</a> command with more general options.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><a href="//godoc.org/code.google.com/p/go.tools/cmd/godoc/">godoc</a></td>
|
||||
<td><a href="//godoc.org/golang.org/x/tools/cmd/godoc/">godoc</a></td>
|
||||
<td> </td>
|
||||
<td>Godoc extracts and generates documentation for Go packages.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><a href="//godoc.org/code.google.com/p/go.tools/cmd/vet/">vet</a></td>
|
||||
<td><a href="//godoc.org/golang.org/x/tools/cmd/vet/">vet</a></td>
|
||||
<td> </td>
|
||||
<td>Vet examines Go source code and reports suspicious constructs, such as Printf
|
||||
calls whose arguments do not align with the format string.</td>
|
||||
|
||||
185
doc/code.html
185
doc/code.html
@@ -60,37 +60,35 @@ To give you an idea of how a workspace looks in practice, here's an example:
|
||||
|
||||
<pre>
|
||||
bin/
|
||||
streak # command executable
|
||||
todo # command executable
|
||||
hello # command executable
|
||||
outyet # command executable
|
||||
pkg/
|
||||
linux_amd64/
|
||||
code.google.com/p/goauth2/
|
||||
oauth.a # package object
|
||||
github.com/nf/todo/
|
||||
task.a # package object
|
||||
github.com/golang/example/
|
||||
stringutil.a # package object
|
||||
src/
|
||||
code.google.com/p/goauth2/
|
||||
.hg/ # mercurial repository metadata
|
||||
oauth/
|
||||
oauth.go # package source
|
||||
oauth_test.go # test source
|
||||
github.com/nf/
|
||||
streak/
|
||||
.git/ # git repository metadata
|
||||
oauth.go # command source
|
||||
streak.go # command source
|
||||
todo/
|
||||
.git/ # git repository metadata
|
||||
task/
|
||||
task.go # package source
|
||||
todo.go # command source
|
||||
<a href="https://github.com/golang/example/">github.com/golang/example/</a>
|
||||
.git/ # Git repository metadata
|
||||
hello/
|
||||
hello.go # command source
|
||||
outyet/
|
||||
main.go # command source
|
||||
main_test.go # test source
|
||||
stringutil/
|
||||
reverse.go # package source
|
||||
reverse_test.go # test source
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
This workspace contains three repositories (<code>goauth2</code>,
|
||||
<code>streak</code>, and <code>todo</code>) comprising two commands
|
||||
(<code>streak</code> and <code>todo</code>) and two libraries
|
||||
(<code>oauth</code> and <code>task</code>).
|
||||
This workspace contains one repository (<code>example</code>)
|
||||
comprising two commands (<code>hello</code> and <code>outyet</code>)
|
||||
and one library (<code>stringutil</code>).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A typical workspace would contain many source repositories containing many
|
||||
packages and commands. Most Go programmers keep <i>all</i> their Go source code
|
||||
and dependencies in a single workspace.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -277,29 +275,29 @@ Let's write a library and use it from the <code>hello</code> program.
|
||||
|
||||
<p>
|
||||
Again, the first step is to choose a package path (we'll use
|
||||
<code>github.com/user/newmath</code>) and create the package directory:
|
||||
<code>github.com/user/stringutil</code>) and create the package directory:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ <b>mkdir $GOPATH/src/github.com/user/newmath</b>
|
||||
$ <b>mkdir $GOPATH/src/github.com/user/stringutil</b>
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Next, create a file named <code>sqrt.go</code> in that directory with the
|
||||
Next, create a file named <code>reverse.go</code> in that directory with the
|
||||
following contents.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
// Package newmath is a trivial example package.
|
||||
package newmath
|
||||
// Package stringutil contains utility functions for working with strings.
|
||||
package stringutil
|
||||
|
||||
// Sqrt returns an approximation to the square root of x.
|
||||
func Sqrt(x float64) float64 {
|
||||
z := 1.0
|
||||
for i := 0; i < 1000; i++ {
|
||||
z -= (z*z - x) / (2 * z)
|
||||
// Reverse returns its argument string reversed rune-wise left to right.
|
||||
func Reverse(s string) string {
|
||||
r := []rune(s)
|
||||
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
|
||||
r[i], r[j] = r[j], r[i]
|
||||
}
|
||||
return z
|
||||
return string(r)
|
||||
}
|
||||
</pre>
|
||||
|
||||
@@ -308,7 +306,7 @@ Now, test that the package compiles with <code>go build</code>:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ <b>go build github.com/user/newmath</b>
|
||||
$ <b>go build github.com/user/stringutil</b>
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
@@ -326,7 +324,7 @@ directory of the workspace.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
After confirming that the <code>newmath</code> package builds,
|
||||
After confirming that the <code>stringutil</code> package builds,
|
||||
modify your original <code>hello.go</code> (which is in
|
||||
<code>$GOPATH/src/github.com/user/hello</code>) to use it:
|
||||
</p>
|
||||
@@ -337,18 +335,18 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
<b>"github.com/user/newmath"</b>
|
||||
<b>"github.com/user/stringutil"</b>
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Printf("Hello, world. <b>Sqrt(2) = %v\n", newmath.Sqrt(2)</b>)
|
||||
fmt.Printf(stringutil.Reverse("!oG ,olleH"))
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Whenever the <code>go</code> tool installs a package or binary, it also
|
||||
installs whatever dependencies it has. So when you install the <code>hello</code>
|
||||
program
|
||||
installs whatever dependencies it has.
|
||||
So when you install the <code>hello</code> program
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
@@ -356,16 +354,16 @@ $ <b>go install github.com/user/hello</b>
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
the <code>newmath</code> package will be installed as well, automatically.
|
||||
the <code>stringutil</code> package will be installed as well, automatically.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Running the new version of the program, you should see some numerical output:
|
||||
Running the new version of the program, you should see a new, reversed message:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ <b>hello</b>
|
||||
Hello, world. Sqrt(2) = 1.414213562373095
|
||||
Hello, Go!
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
@@ -374,22 +372,22 @@ After the steps above, your workspace should look like this:
|
||||
|
||||
<pre>
|
||||
bin/
|
||||
hello # command executable
|
||||
hello # command executable
|
||||
pkg/
|
||||
linux_amd64/ # this will reflect your OS and architecture
|
||||
linux_amd64/ # this will reflect your OS and architecture
|
||||
github.com/user/
|
||||
newmath.a # package object
|
||||
stringutil.a # package object
|
||||
src/
|
||||
github.com/user/
|
||||
hello/
|
||||
hello.go # command source
|
||||
newmath/
|
||||
sqrt.go # package source
|
||||
hello.go # command source
|
||||
stringutil/
|
||||
reverse.go # package source
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Note that <code>go install</code> placed the <code>newmath.a</code> object in a
|
||||
directory inside <code>pkg/linux_amd64</code> that mirrors its source
|
||||
Note that <code>go install</code> placed the <code>stringutil.a</code> object
|
||||
in a directory inside <code>pkg/linux_amd64</code> that mirrors its source
|
||||
directory.
|
||||
This is so that future invocations of the <code>go</code> tool can find the
|
||||
package object and avoid recompiling the package unnecessarily.
|
||||
@@ -457,20 +455,29 @@ if the function calls a failure function such as <code>t.Error</code> or
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Add a test to the <code>newmath</code> package by creating the file
|
||||
<code>$GOPATH/src/github.com/user/newmath/sqrt_test.go</code> containing the
|
||||
following Go code.
|
||||
Add a test to the <code>stringutil</code> package by creating the file
|
||||
<code>$GOPATH/src/github.com/user/stringutil/reverse_test.go</code> containing
|
||||
the following Go code.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
package newmath
|
||||
package stringutil
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestSqrt(t *testing.T) {
|
||||
const in, out = 4, 2
|
||||
if x := Sqrt(in); x != out {
|
||||
t.Errorf("Sqrt(%v) = %v, want %v", in, x, out)
|
||||
func TestReverse(t *testing.T) {
|
||||
cases := []struct {
|
||||
in, want string
|
||||
}{
|
||||
{"Hello, world", "dlrow ,olleH"},
|
||||
{"Hello, 世界", "界世 ,olleH"},
|
||||
{"", ""},
|
||||
}
|
||||
for _, c := range cases {
|
||||
got := Reverse(c.in)
|
||||
if got != c.want {
|
||||
t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
@@ -480,8 +487,8 @@ Then run the test with <code>go test</code>:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ <b>go test github.com/user/newmath</b>
|
||||
ok github.com/user/newmath 0.165s
|
||||
$ <b>go test github.com/user/stringutil</b>
|
||||
ok github.com/user/stringutil 0.165s
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
@@ -491,7 +498,7 @@ directory, you can omit the package path:
|
||||
|
||||
<pre>
|
||||
$ <b>go test</b>
|
||||
ok github.com/user/newmath 0.165s
|
||||
ok github.com/user/stringutil 0.165s
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
@@ -507,16 +514,16 @@ An import path can describe how to obtain the package source code using a
|
||||
revision control system such as Git or Mercurial. The <code>go</code> tool uses
|
||||
this property to automatically fetch packages from remote repositories.
|
||||
For instance, the examples described in this document are also kept in a
|
||||
Mercurial repository hosted at Google Code,
|
||||
<code><a href="//code.google.com/p/go.example">code.google.com/p/go.example</a></code>.
|
||||
Git repository hosted at GitHub
|
||||
<code><a href="https://github.com/golang/example">github.com/golang/example</a></code>.
|
||||
If you include the repository URL in the package's import path,
|
||||
<code>go get</code> will fetch, build, and install it automatically:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ <b>go get code.google.com/p/go.example/hello</b>
|
||||
$ <b>go get github.com/golang/example/hello</b>
|
||||
$ <b>$GOPATH/bin/hello</b>
|
||||
Hello, world. Sqrt(2) = 1.414213562373095
|
||||
Hello, Go examples!
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
@@ -533,43 +540,45 @@ tree should now look like this:
|
||||
|
||||
<pre>
|
||||
bin/
|
||||
hello # command executable
|
||||
hello # command executable
|
||||
pkg/
|
||||
linux_amd64/
|
||||
code.google.com/p/go.example/
|
||||
newmath.a # package object
|
||||
github.com/golang/example/
|
||||
stringutil.a # package object
|
||||
github.com/user/
|
||||
newmath.a # package object
|
||||
stringutil.a # package object
|
||||
src/
|
||||
code.google.com/p/go.example/
|
||||
github.com/golang/example/
|
||||
.git/ # Git repository metadata
|
||||
hello/
|
||||
hello.go # command source
|
||||
newmath/
|
||||
sqrt.go # package source
|
||||
sqrt_test.go # test source
|
||||
hello.go # command source
|
||||
stringutil/
|
||||
reverse.go # package source
|
||||
reverse_test.go # test source
|
||||
github.com/user/
|
||||
hello/
|
||||
hello.go # command source
|
||||
newmath/
|
||||
sqrt.go # package source
|
||||
sqrt_test.go # test source
|
||||
hello.go # command source
|
||||
stringutil/
|
||||
reverse.go # package source
|
||||
reverse_test.go # test source
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The <code>hello</code> command hosted at Google Code depends on the
|
||||
<code>newmath</code> package within the same repository. The imports in
|
||||
<code>hello.go</code> file use the same import path convention, so the <code>go
|
||||
get</code> command is able to locate and install the dependent package, too.
|
||||
The <code>hello</code> command hosted at GitHub depends on the
|
||||
<code>stringutil</code> package within the same repository. The imports in
|
||||
<code>hello.go</code> file use the same import path convention, so the
|
||||
<code>go get</code> command is able to locate and install the dependent
|
||||
package, too.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
import "code.google.com/p/go.example/newmath"
|
||||
import "github.com/golang/example/stringutil"
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
This convention is the easiest way to make your Go packages available for
|
||||
others to use.
|
||||
The <a href="//code.google.com/p/go-wiki/wiki/Projects">Go Wiki</a>
|
||||
The <a href="//golang.org/wiki/Projects">Go Wiki</a>
|
||||
and <a href="//godoc.org/">godoc.org</a>
|
||||
provide lists of external Go projects.
|
||||
</p>
|
||||
@@ -618,5 +627,5 @@ The official mailing list for discussion of the Go language is
|
||||
|
||||
<p>
|
||||
Report bugs using the
|
||||
<a href="//code.google.com/p/go/issues/list">Go issue tracker</a>.
|
||||
<a href="//golang.org/issue">Go issue tracker</a>.
|
||||
</p>
|
||||
|
||||
@@ -30,21 +30,16 @@ We encourage all Go users to subscribe to
|
||||
<h2 id="go1">Version history</h2>
|
||||
|
||||
<h3 id="release"><a href="/doc/devel/release.html">Release History</a></h3>
|
||||
<p>A summary of the changes between Go releases.</p>
|
||||
|
||||
<h4 id="go1notes"><a href="/doc/go1">Go 1 Release Notes</a></h4>
|
||||
<p>
|
||||
A guide for updating your code to work with Go 1.
|
||||
</p>
|
||||
<p>A <a href="/doc/devel/release.html">summary</a> of the changes between Go releases. Notes for the major releases:</p>
|
||||
|
||||
<h4 id="release notes"><a href="/doc/go1.1">Go 1.1 Release Notes</a></h4>
|
||||
<p>
|
||||
A list of significant changes in Go 1.1, with instructions for updating
|
||||
your code where necessary.
|
||||
Each point release includes a similar document appropriate for that
|
||||
release: <a href="/doc/go1.2">Go 1.2</a>, <a href="/doc/go1.3">Go 1.3</a>,
|
||||
and so on.
|
||||
</p>
|
||||
<ul>
|
||||
<li><a href="/doc/go1.4">Go 1.4</a> <small>(December 2014)</small></li>
|
||||
<li><a href="/doc/go1.3">Go 1.3</a> <small>(June 2014)</small></li>
|
||||
<li><a href="/doc/go1.2">Go 1.2</a> <small>(December 2013)</small></li>
|
||||
<li><a href="/doc/go1.1">Go 1.1</a> <small>(May 2013)</small></li>
|
||||
<li><a href="/doc/go1">Go 1</a> <small>(March 2012)</small></li>
|
||||
</ul>
|
||||
|
||||
<h3 id="go1compat"><a href="/doc/go1compat">Go 1 and the Future of Go Programs</a></h3>
|
||||
<p>
|
||||
@@ -55,7 +50,7 @@ Go 1 matures.
|
||||
|
||||
<h2 id="resources">Developer Resources</h2>
|
||||
|
||||
<h3 id="source"><a href="https://code.google.com/p/go/source">Source Code</a></h3>
|
||||
<h3 id="source"><a href="https://golang.org/change">Source Code</a></h3>
|
||||
<p>Check out the Go source code.</p>
|
||||
|
||||
<h3 id="golang-dev"><a href="https://groups.google.com/group/golang-dev">Developer</a> and
|
||||
@@ -81,13 +76,13 @@ systems and architectures.</p>
|
||||
|
||||
<h2 id="howto">How you can help</h2>
|
||||
|
||||
<h3><a href="https://code.google.com/p/go/issues">Reporting issues</a></h3>
|
||||
<h3><a href="//golang.org/issue">Reporting issues</a></h3>
|
||||
|
||||
<p>
|
||||
If you spot bugs, mistakes, or inconsistencies in the Go project's code or
|
||||
documentation, please let us know by
|
||||
<a href="https://code.google.com/p/go/issues/entry">filing a ticket</a>
|
||||
on our <a href="https://code.google.com/p/go/issues">issue tracker</a>.
|
||||
<a href="//golang.org/issue/new">filing a ticket</a>
|
||||
on our <a href="//golang.org/issue">issue tracker</a>.
|
||||
(Of course, you should check it's not an existing issue before creating
|
||||
a new one.)
|
||||
</p>
|
||||
@@ -106,8 +101,8 @@ To get started, read these <a href="/doc/contribute.html">contribution
|
||||
guidelines</a> for information on design, testing, and our code review process.
|
||||
</p>
|
||||
<p>
|
||||
Check <a href="https://code.google.com/p/go/issues">the tracker</a> for
|
||||
Check <a href="//golang.org/issue">the tracker</a> for
|
||||
open issues that interest you. Those labeled
|
||||
<a href="https://code.google.com/p/go/issues/list?q=status=HelpWanted">HelpWanted</a>
|
||||
<a href="https://github.com/golang/go/issues?q=is%3Aopen+is%3Aissue+label%3Ahelpwanted">helpwanted</a>
|
||||
are particularly in need of outside help.
|
||||
</p>
|
||||
|
||||
@@ -6,9 +6,12 @@
|
||||
|
||||
<p>
|
||||
This document explains how to contribute changes to the Go project.
|
||||
It assumes you have installed Go using the
|
||||
It assumes you have followed the
|
||||
<a href="/doc/install/source">installation instructions</a> and
|
||||
have <a href="code.html">written and tested your code</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
(Note that the <code>gccgo</code> frontend lives elsewhere;
|
||||
see <a href="gccgo_contribute.html">Contributing to gccgo</a>.)
|
||||
</p>
|
||||
@@ -54,7 +57,8 @@ $ ./all.bash
|
||||
</p>
|
||||
|
||||
<p>
|
||||
After running for a while, the command should print "<code>ALL TESTS PASSED</code>".
|
||||
After running for a while, the command should print
|
||||
"<code>ALL</code> <code>TESTS</code> <code>PASSED</code>".
|
||||
</p>
|
||||
|
||||
<h2 id="Code_review">Code review</h2>
|
||||
@@ -64,208 +68,230 @@ Changes to Go must be reviewed before they are submitted,
|
||||
no matter who makes the change.
|
||||
(In exceptional cases, such as fixing a build, the review can
|
||||
follow shortly after submitting.)
|
||||
A Mercurial extension helps manage the code review process.
|
||||
The extension is included in the Go source tree but needs
|
||||
to be added to your Mercurial configuration.
|
||||
A custom git command called <code>git-codereview</code>,
|
||||
discussed below, helps manage the code review process through a Google-hosted
|
||||
<a href="https://go-review.googlesource.com/">instance</a> of the code review
|
||||
system called <a href="https://code.google.com/p/gerrit/">Gerrit</a>.
|
||||
</p>
|
||||
|
||||
<h3>Caveat for Mercurial aficionados</h3>
|
||||
<h3>Set up authentication for code review</h3>
|
||||
|
||||
<p>
|
||||
<i>Using Mercurial with the code review extension is not the same
|
||||
as using standard Mercurial.</i>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The Go repository is maintained as a single line of reviewed changes;
|
||||
we prefer to avoid the complexity of Mercurial's arbitrary change graph.
|
||||
The code review extension helps here: its <code>hg submit</code> command
|
||||
automatically checks for and warns about the local repository
|
||||
being out of date compared to the remote one.
|
||||
The <code>hg submit</code> command also verifies other
|
||||
properties about the Go repository.
|
||||
For example,
|
||||
it checks that Go code being checked in is formatted in the standard style,
|
||||
as defined by <a href="/cmd/gofmt">gofmt</a>,
|
||||
and it checks that the author of the code is properly recorded for
|
||||
<a href="#copyright">copyright purposes</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To help ensure changes are only created by <code>hg submit</code>,
|
||||
the code review extension disables the standard <code>hg commit</code>
|
||||
command.
|
||||
</p>
|
||||
|
||||
<h3>Configure the extension</h3>
|
||||
|
||||
<p>Edit <code>.hg/hgrc</code> in the root of your Go checkout to add:</p>
|
||||
|
||||
<pre>
|
||||
[extensions]
|
||||
codereview = /path/to/go/lib/codereview/codereview.py
|
||||
|
||||
[ui]
|
||||
username = Your Name <you@server.dom>
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The <code>username</code> information will not be used unless
|
||||
you are a committer (see below), but Mercurial complains if it is missing.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As the codereview extension is only enabled for your Go checkout, the remainder of this document assumes you
|
||||
are inside the go directory when issuing commands.
|
||||
</p>
|
||||
|
||||
<p>To contribute to subrepositories, edit the <code>.hg/hgrc</code> for each
|
||||
subrepository in the same way. For example, add the codereview extension to
|
||||
<code>code.google.com/p/go.tools/.hg/hgrc</code>.
|
||||
</p>
|
||||
|
||||
<h3>Understanding the extension</h3>
|
||||
|
||||
<p>After adding the code review extension, you can run</p>
|
||||
|
||||
<pre>
|
||||
$ hg help codereview
|
||||
</pre>
|
||||
|
||||
<p>to learn more about its commands. To learn about a specific code-review-specific
|
||||
command such as <code>change</code>, run</p>
|
||||
|
||||
<pre>
|
||||
$ hg help change
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Windows users may need to perform extra steps to get the code review
|
||||
extension working. See the
|
||||
<a href="https://code.google.com/p/go-wiki/wiki/CodeReview">CodeReview page</a>
|
||||
on the <a href="https://code.google.com/p/go-wiki/wiki">Go Wiki</a> for details.
|
||||
</p>
|
||||
|
||||
<h3>Log in to the code review site.</h3>
|
||||
|
||||
<p>
|
||||
The code review server uses a Google Account to authenticate.
|
||||
The Git code hosting server and Gerrit code review server both use a Google
|
||||
Account to authenticate. You therefore need a Google Account to proceed.
|
||||
(If you can use the account to
|
||||
<a href="https://www.google.com/accounts/Login?hl=en&continue=http://www.google.com/">sign in at google.com</a>,
|
||||
<a href="https://www.google.com/accounts/Login">sign in at google.com</a>,
|
||||
you can use it to sign in to the code review server.)
|
||||
The email address you use on the Code Review site
|
||||
will be recorded in the <a href="https://code.google.com/p/go/source/list">Mercurial change log</a>
|
||||
The email address you use with the code review system
|
||||
will be recorded in the <a href="https://go.googlesource.com/go">change log</a>
|
||||
and in the <a href="/CONTRIBUTORS"><code>CONTRIBUTORS</code></a> file.
|
||||
You can <a href="https://www.google.com/accounts/NewAccount">create a Google Account</a>
|
||||
associated with any address where you receive email.
|
||||
If you've enabled the two-step verification feature, don't forget to generate an
|
||||
application-specific password and use that when prompted for a password.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Visit the site <a href="https://go.googlesource.com">go.googlesource.com</a>
|
||||
and log in using your Google Account.
|
||||
Click on the "Generate Password" link that appears at the top of the page.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Click the radio button that says "Only <code>go.googlesource.com</code>"
|
||||
to use this authentication token only for the Go project.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Further down the page is a box containing commands to install
|
||||
the authentication cookie in file called <code>.gitcookies</code> in your home
|
||||
directory.
|
||||
Copy the text for the commands into a Unix shell window to execute it.
|
||||
That will install the authentication token.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
(If you are on a Windows computer, you should instead follow the instructions
|
||||
in the yellow box to run the command.)
|
||||
</p>
|
||||
|
||||
<h3>Register with Gerrit</h3>
|
||||
|
||||
<p>
|
||||
Now that you have a Google account and the authentication token,
|
||||
you need to register your account with Gerrit, the code review system.
|
||||
To do this, visit <a href="https://golang.org/cl">golang.org/cl</a>
|
||||
and log in using the same Google Account you used above.
|
||||
That is all that is required.
|
||||
</p>
|
||||
|
||||
<h3>Install the git-codereview command</h3>
|
||||
|
||||
<p>
|
||||
Now install the <code>git-codereview</code> command by running,
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ hg code-login
|
||||
Email (login for uploading to codereview.appspot.com): rsc@golang.org
|
||||
Password for rsc@golang.org:
|
||||
|
||||
Saving authentication cookies to /Users/rsc/.codereview_upload_cookies_codereview.appspot.com
|
||||
go get -u golang.org/x/review/git-codereview
|
||||
</pre>
|
||||
|
||||
<h3>Configure your account settings.</h3>
|
||||
|
||||
<p>Edit your <a href="https://codereview.appspot.com/settings">code review settings</a>.
|
||||
Grab a nickname.
|
||||
Many people prefer to set the Context option to
|
||||
“Whole file” to see more context when reviewing changes.
|
||||
<p>
|
||||
Make sure <code>git-codereview</code> is installed in your shell path, so that the
|
||||
<code>git</code> command can find it. Check that
|
||||
</p>
|
||||
|
||||
<p>Once you have chosen a nickname in the settings page, others
|
||||
can use that nickname as a shorthand for naming reviewers and the CC list.
|
||||
For example, <code>rsc</code> is an alias for <code>rsc@golang.org</code>.
|
||||
<pre>
|
||||
$ git codereview help
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
prints help text, not an error.
|
||||
</p>
|
||||
|
||||
<h3>Switch to the default branch</h3>
|
||||
<p>
|
||||
Note to Git aficionados: The <code>git-codereview</code> command is not required to
|
||||
upload and manage Gerrit code reviews. For those who prefer plain Git, the text
|
||||
below gives the Git equivalent of each git-codereview command. If you do use plain
|
||||
Git, note that you still need the commit hooks that the git-codereview command
|
||||
configures; those hooks add a Gerrit <code>Change-Id</code> line to the commit
|
||||
message and check that all Go source files have been formatted with gofmt. Even
|
||||
if you intend to use plain Git for daily work, install the hooks in a new Git
|
||||
checkout by running <code>git-codereview</code> <code>hooks</code>.
|
||||
</p>
|
||||
|
||||
<h3>Set up git aliases</h3>
|
||||
|
||||
<p>
|
||||
The <code>git-codereview</code> command can be run directly from the shell
|
||||
by typing, for instance,
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ git codereview sync
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
but it is more convenient to set up aliases for <code>git-codereview</code>'s own
|
||||
subcommands, so that the above becomes,
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ git sync
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The <code>git-codereview</code> subcommands have been chosen to be distinct from
|
||||
Git's own, so it's safe to do so.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The aliases are optional, but in the rest of this document we will assume
|
||||
they are installed.
|
||||
To install them, copy this text into your Git configuration file
|
||||
(usually <code>.gitconfig</code> in your home directory):
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
[alias]
|
||||
change = codereview change
|
||||
gofmt = codereview gofmt
|
||||
mail = codereview mail
|
||||
pending = codereview pending
|
||||
submit = codereview submit
|
||||
sync = codereview sync
|
||||
</pre>
|
||||
|
||||
<h3>Understanding the git-codereview command</h3>
|
||||
|
||||
<p>After installing the <code>git-codereview</code> command, you can run</p>
|
||||
|
||||
<pre>
|
||||
$ git codereview help
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
to learn more about its commands.
|
||||
You can also read the <a href="https://godoc.org/golang.org/x/review/git-codereview">command documentation</a>.
|
||||
</p>
|
||||
|
||||
<h3>Switch to the master branch</h3>
|
||||
|
||||
<p>
|
||||
Most Go installations use a release branch, but new changes should
|
||||
only be made to the default branch. (They may be applied later to a release
|
||||
branch as part of the release process.)
|
||||
Before making a change, make sure you use the default branch:
|
||||
only be made based on the master branch.
|
||||
(They may be applied later to a release branch as part of the release process,
|
||||
but most contributors won't do this themselves.)
|
||||
Before making a change, make sure you start on the master branch:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ hg update default
|
||||
$ git checkout master
|
||||
$ git sync
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
(In Git terms, <code>git</code> <code>sync</code> runs
|
||||
<code>git</code> <code>pull</code> <code>-r</code>.)
|
||||
</p>
|
||||
|
||||
<h3>Make a change</h3>
|
||||
|
||||
<p>
|
||||
The entire checked-out tree is writable.
|
||||
If you need to edit files, just edit them: Mercurial will figure out which ones changed.
|
||||
You do need to inform Mercurial of added, removed, copied, or renamed files,
|
||||
by running
|
||||
<code>hg add</code>,
|
||||
<code>hg rm</code>,
|
||||
<code>hg cp</code>,
|
||||
or
|
||||
<code>hg mv</code>.
|
||||
Once you have edited files, you must tell Git that they have been modified.
|
||||
You must also tell Git about any files that are added, removed, or renamed files.
|
||||
These operations are done with the usual Git commands,
|
||||
<code>git</code> <code>add</code>,
|
||||
<code>git</code> <code>rm</code>,
|
||||
and
|
||||
<code>git</code> <code>mv</code>.
|
||||
</p>
|
||||
|
||||
<p>When you are ready to send a change out for review, run</p>
|
||||
<p>
|
||||
If you wish to checkpoint your work, or are ready to send the code out for review, run</p>
|
||||
|
||||
<pre>
|
||||
$ hg change
|
||||
$ git change <i><branch></i>
|
||||
</pre>
|
||||
|
||||
<p>from any directory in your Go repository.
|
||||
Mercurial will open a change description file in your editor.
|
||||
(It uses the editor named by the <code>$EDITOR</code> environment variable, <code>vi</code> by default.)
|
||||
<p>
|
||||
from any directory in your Go repository to commit the changes so far.
|
||||
The name <i><branch></i> is an arbitrary one you choose to identify the
|
||||
local branch containing your changes.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
(In Git terms, <code>git</code> <code>change</code> <code><branch></code>
|
||||
runs <code>git</code> <code>checkout</code> <code>-b</code> <code>branch</code>,
|
||||
then <code>git</code> <code>branch</code> <code>--set-upstream-to</code> <code>origin/master</code>,
|
||||
then <code>git</code> <code>commit</code>.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Git will open a change description file in your editor.
|
||||
(It uses the editor named by the <code>$EDITOR</code> environment variable,
|
||||
<code>vi</code> by default.)
|
||||
The file will look like:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
# Change list.
|
||||
# Lines beginning with # are ignored.
|
||||
# Multi-line values should be indented.
|
||||
|
||||
Reviewer:
|
||||
CC:
|
||||
|
||||
Description:
|
||||
<enter description here>
|
||||
|
||||
Files:
|
||||
src/math/sin.go
|
||||
src/math/tan.go
|
||||
src/regexp/regexp.go
|
||||
# Please enter the commit message for your changes. Lines starting
|
||||
# with '#' will be ignored, and an empty message aborts the commit.
|
||||
# On branch foo
|
||||
# Changes not staged for commit:
|
||||
# modified: editedfile.go
|
||||
#
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The <code>Reviewer</code> line lists the reviewers assigned
|
||||
to this change, and the <code>CC</code> line lists people to
|
||||
notify about the change.
|
||||
These can be code review nicknames or arbitrary email addresses.
|
||||
Unless explicitly told otherwise, such as in the discussion leading
|
||||
up to sending in the change list, leave the reviewer field blank.
|
||||
This means that the
|
||||
<a href="https://groups.google.com/group/golang-codereviews">golang-codereviews@googlegroups.com</a>
|
||||
mailing list will be used as the reviewer.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Replace “<code><enter description here></code>”
|
||||
with a description of your change.
|
||||
At the beginning of this file is a blank line; replace it
|
||||
with a thorough description of your change.
|
||||
The first line of the change description is conventionally a one-line
|
||||
summary of the change, prefixed by the primary affected package,
|
||||
and is used as the subject for code review mail; the rest of the
|
||||
description elaborates.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The <code>Files</code> section lists all the modified files
|
||||
in your client.
|
||||
It is best to keep unrelated changes in different change lists.
|
||||
In this example, we can include just the changes to package <code>math</code>
|
||||
by deleting the line mentioning <code>regexp.go</code>.
|
||||
and is used as the subject for code review mail.
|
||||
The rest of the
|
||||
description elaborates and should provide context for the
|
||||
change and explain what it does.
|
||||
If there is a helpful reference, mention it here.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -273,343 +299,314 @@ After editing, the template might now read:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
# Change list.
|
||||
# Lines beginning with # are ignored.
|
||||
# Multi-line values should be indented.
|
||||
math: improved Sin, Cos and Tan precision for very large arguments
|
||||
|
||||
Reviewer: golang-codereviews@googlegroups.com
|
||||
CC: math-nuts@swtch.com
|
||||
The existing implementation has poor numerical properties for
|
||||
large arguments, so use the McGillicutty algorithm to improve
|
||||
accuracy above 1e10.
|
||||
|
||||
Description:
|
||||
math: improved Sin, Cos and Tan precision for very large arguments.
|
||||
The algorithm is described at http://wikipedia.org/wiki/McGillicutty_Algorithm
|
||||
|
||||
See Bimmler and Shaney, ``Extreme sinusoids,'' J. Math 3(14).
|
||||
Fixes issue 159.
|
||||
Fixes #159
|
||||
|
||||
Files:
|
||||
src/math/sin.go
|
||||
src/math/tan.go
|
||||
# Please enter the commit message for your changes. Lines starting
|
||||
# with '#' will be ignored, and an empty message aborts the commit.
|
||||
# On branch foo
|
||||
# Changes not staged for commit:
|
||||
# modified: editedfile.go
|
||||
#
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The special sentence “Fixes issue 159.” associates
|
||||
the change with issue 159 in the <a href="https://code.google.com/p/go/issues/list">Go issue tracker</a>.
|
||||
When this change is eventually submitted, the issue
|
||||
tracker will automatically mark the issue as fixed.
|
||||
(These conventions are described in detail by the
|
||||
<a href="https://code.google.com/p/support/wiki/IssueTracker#Integration_with_version_control">Google Project Hosting Issue Tracker documentation</a>.)
|
||||
The commented section of the file lists all the modified files in your client.
|
||||
It is best to keep unrelated changes in different change lists,
|
||||
so if you see a file listed that should not be included, abort
|
||||
the command and move that file to a different branch.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Save the file and exit the editor.</p>
|
||||
The special notation "Fixes #159" associates the change with issue 159 in the
|
||||
<a href="https://golang.org/issue/159">Go issue tracker</a>.
|
||||
When this change is eventually submitted, the issue
|
||||
tracker will automatically mark the issue as fixed.
|
||||
(There are several such conventions, described in detail in the
|
||||
<a href="https://help.github.com/articles/closing-issues-via-commit-messages/">GitHub Issue Tracker documentation</a>.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The code review server assigns your change an issue number and URL,
|
||||
which <code>hg change</code> will print, something like:
|
||||
Once you have finished writing the commit message,
|
||||
save the file and exit the editor.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you wish to do more editing, re-stage your changes using
|
||||
<code>git</code> <code>add</code>, and then run
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
CL created: https://codereview.appspot.com/99999
|
||||
$ git change
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
to update the change description and incorporate the staged changes. The
|
||||
change description contains a <code>Change-Id</code> line near the bottom,
|
||||
added by a Git commit hook during the initial
|
||||
<code>git</code> <code>change</code>.
|
||||
That line is used by Gerrit to match successive uploads of the same change.
|
||||
Do not edit or delete it.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
(In Git terms, <code>git</code> <code>change</code> with no branch name
|
||||
runs <code>git</code> <code>commit</code> <code>--amend</code>.)
|
||||
</p>
|
||||
|
||||
<h3>Mail the change for review</h3>
|
||||
|
||||
<p>
|
||||
Creating or uploading the change uploads a copy of the diff to the code review server,
|
||||
but it does not notify anyone about it. To do that, you need to run <code>hg mail</code>
|
||||
(see below).
|
||||
</p>
|
||||
|
||||
<p>To send out a change for review, run <code>hg mail</code> using the change list number
|
||||
assigned during <code>hg change</code>:</p>
|
||||
|
||||
<pre>
|
||||
$ hg mail 99999
|
||||
</pre>
|
||||
|
||||
<p>You can add to the <code>Reviewer:</code> and <code>CC:</code> lines
|
||||
using the <code>-r</code> or <code>--cc</code> options.
|
||||
In the above example, we could have left the <code>Reviewer</code> and <code>CC</code>
|
||||
lines blank and then run:
|
||||
Once the change is ready, mail it out for review:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ hg mail -r golang-codereviews@googlegroups.com --cc math-nuts@swtch.com 99999
|
||||
$ git mail
|
||||
</pre>
|
||||
|
||||
<p>to achieve the same effect.</p>
|
||||
<p>
|
||||
You can specify a reviewer or CC interested parties
|
||||
using the <code>-r</code> or <code>-cc</code> options.
|
||||
Both accept a comma-separated list of email addresses:
|
||||
</p>
|
||||
|
||||
<p>Note that <code>-r</code> and <code>--cc</code> cannot be spelled <code>--r</code> or <code>-cc</code>.</p>
|
||||
<pre>
|
||||
$ git mail -r joe@golang.org -cc mabel@example.com,math-nuts@swtch.com
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Unless explicitly told otherwise, such as in the discussion leading
|
||||
up to sending in the change list, it's better not to specify a reviewer.
|
||||
All changes are automatically CC'ed to the
|
||||
<a href="https://groups.google.com/group/golang-codereviews">golang-codereviews@googlegroups.com</a>
|
||||
mailing list.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
(In Git terms, <code>git</code> <code>mail</code> pushes the local committed
|
||||
changes to Gerrit using <code>git</code> <code>push</code> <code>origin</code>
|
||||
<code>HEAD:refs/for/master</code>.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If your change relates to an open issue, please add a comment to the issue
|
||||
announcing your proposed fix, including a link to your CL.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The code review server assigns your change an issue number and URL,
|
||||
which <code>git</code> <code>mail</code> will print, something like:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
remote: New Changes:
|
||||
remote: https://go-review.googlesource.com/99999 math: improved Sin, Cos and Tan precision for very large arguments
|
||||
</pre>
|
||||
|
||||
<h3>Reviewing code</h3>
|
||||
|
||||
<p>
|
||||
Running <code>hg mail</code> will send an email to you and the reviewers
|
||||
asking them to visit the issue's URL and make comments on the change.
|
||||
When done, the reviewer clicks “Publish and Mail comments”
|
||||
to send comments back.
|
||||
Running <code>git</code> <code>mail</code> will send an email to you and the
|
||||
reviewers asking them to visit the issue's URL and make comments on the change.
|
||||
When done, the reviewer adds comments through the Gerrit user interface
|
||||
and clicks "Reply" to send comments back.
|
||||
You will receive a mail notification when this happens.
|
||||
You must reply through the web interface.
|
||||
(Unlike with the old Rietveld review system, replying by mail has no effect.)
|
||||
</p>
|
||||
|
||||
|
||||
<h3>Revise and upload</h3>
|
||||
|
||||
<p>
|
||||
You must respond to review comments through the web interface.
|
||||
(Unlike with the old Rietveld review system, responding by mail has no effect.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When you have revised the code and are ready for another round of review,
|
||||
you can upload your change and send mail asking the reviewers to
|
||||
please take another look (<code>PTAL</code>). Use the change list number
|
||||
assigned during <code>hg change</code>
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ hg mail 99999
|
||||
</pre>
|
||||
|
||||
|
||||
<p>
|
||||
Or to upload your change without sending a notification, run
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ hg upload 99999
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
You will probably revise your code in response to the reviewer comments.
|
||||
You might also visit the code review web page and reply to the comments,
|
||||
letting the reviewer know that you've addressed them or explain why you
|
||||
haven't. When you're done replying, click “Publish and Mail comments”
|
||||
to send the line-by-line replies and any other comments.
|
||||
stage those changes and use <code>git</code> <code>change</code> to update the
|
||||
commit.
|
||||
To send the update change list for another round of review,
|
||||
run <code>git</code> <code>mail</code> again.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The reviewer can comment on the new copy, and the process repeats.
|
||||
The reviewer approves the change by replying with a mail that says
|
||||
<code>LGTM</code>: looks good to me.
|
||||
The reviewer approves the change by giving it a positive score
|
||||
(+1 or +2) and replying <code>LGTM</code>: looks good to me.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You can see a list of your pending changes by running <code>hg pending</code> (<code>hg p</code> for short).
|
||||
</p>
|
||||
|
||||
<h3>Adding or removing files from an existing change</h3>
|
||||
|
||||
<p>
|
||||
If you need to re-edit the change description, or change the files included in the CL,
|
||||
run <code>hg change 99999</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Alternatively, you can use
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ hg file 99999 somefile
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
to add <code>somefile</code> to CL 99999, and
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ hg file -d 99999 somefile
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
to remove <code>somefile</code> from the CL.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A file may only belong to a single active CL at a time. <code>hg file</code>
|
||||
will issue a warning if a file is moved between changes.
|
||||
You can see a list of your pending changes by running <code>git</code>
|
||||
<code>pending</code>, and switch between change branches with <code>git</code>
|
||||
<code>change</code> <code><i><branch></i></code>.
|
||||
</p>
|
||||
|
||||
<h3>Synchronize your client</h3>
|
||||
|
||||
<p>While you were working, others might have submitted changes
|
||||
to the repository. To update your client, run</p>
|
||||
<p>
|
||||
While you were working, others might have submitted changes to the repository.
|
||||
To update your local branch, run
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ hg sync
|
||||
$ git sync
|
||||
</pre>
|
||||
|
||||
<p>(For Mercurial fans, <code>hg sync</code> runs <code>hg pull -u</code>
|
||||
but then also synchronizes the local change list state against the new data.)</p>
|
||||
|
||||
<p>
|
||||
If files you were editing have changed, Mercurial does its best to merge the
|
||||
remote changes into your local changes. It may leave some files to merge by hand.
|
||||
(In git terms, <code>git</code> <code>sync</code> runs
|
||||
<code>git</code> <code>pull</code> <code>-r</code>.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For example, suppose you have edited <code>flag_test.go</code> but
|
||||
If files you were editing have changed, Git does its best to merge the
|
||||
remote changes into your local changes.
|
||||
It may leave some files to merge by hand.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For example, suppose you have edited <code>sin.go</code> but
|
||||
someone else has committed an independent change.
|
||||
When you run <code>hg sync</code>, you will get the (scary-looking) output
|
||||
(emphasis added):
|
||||
When you run <code>git</code> <code>sync</code>,
|
||||
you will get the (scary-looking) output:
|
||||
|
||||
<pre>
|
||||
$ hg sync
|
||||
adding changesets
|
||||
adding manifests
|
||||
adding file changes
|
||||
added 1 changeset with 2 changes to 2 files
|
||||
getting src/flag/flag.go
|
||||
couldn't find merge tool hgmerge
|
||||
merging src/flag/flag_test.go
|
||||
warning: conflicts during merge.
|
||||
<i>merging src/flag/flag_test.go failed!</i>
|
||||
1 file updated, 0 files merged, 0 files removed, 1 file unresolved
|
||||
use 'hg resolve' to retry unresolved file merges
|
||||
$
|
||||
$ git sync
|
||||
Failed to merge in the changes.
|
||||
Patch failed at 0023 math: improved Sin, Cos and Tan precision for very large arguments
|
||||
The copy of the patch that failed is found in:
|
||||
/home/you/repo/.git/rebase-apply/patch
|
||||
|
||||
When you have resolved this problem, run "git rebase --continue".
|
||||
If you prefer to skip this patch, run "git rebase --skip" instead.
|
||||
To check out the original branch and stop rebasing, run "git rebase --abort".
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The only important part in that transcript is the italicized line:
|
||||
Mercurial failed to merge your changes with the independent change.
|
||||
When this happens, Mercurial leaves both edits in the file,
|
||||
marked by <code><<<<<<<</code> and
|
||||
If this happens, run
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ git status
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
to see which files failed to merge.
|
||||
The output will look something like this:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
rebase in progress; onto a24c3eb
|
||||
You are currently rebasing branch 'mcgillicutty' on 'a24c3eb'.
|
||||
(fix conflicts and then run "git rebase --continue")
|
||||
(use "git rebase --skip" to skip this patch)
|
||||
(use "git rebase --abort" to check out the original branch)
|
||||
|
||||
Unmerged paths:
|
||||
(use "git reset HEAD <file>..." to unstage)
|
||||
(use "git add <file>..." to mark resolution)
|
||||
|
||||
<i>both modified: sin.go</i>
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The only important part in that transcript is the italicized "both modified"
|
||||
line: Git failed to merge your changes with the conflicting change.
|
||||
When this happens, Git leaves both sets of edits in the file,
|
||||
with conflicts marked by <code><<<<<<<</code> and
|
||||
<code>>>>>>>></code>.
|
||||
It is now your job to edit the file to combine them.
|
||||
Continuing the example, searching for those strings in <code>flag_test.go</code>
|
||||
Continuing the example, searching for those strings in <code>sin.go</code>
|
||||
might turn up:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
VisitAll(visitor);
|
||||
<<<<<<< local
|
||||
if len(m) != 7 {
|
||||
arg = scale(arg)
|
||||
<<<<<<< HEAD
|
||||
if arg > 1e9 {
|
||||
=======
|
||||
if len(m) != 8 {
|
||||
>>>>>>> other
|
||||
t.Error("VisitAll misses some flags");
|
||||
if arg > 1e10 {
|
||||
>>>>>>> mcgillicutty
|
||||
largeReduce(arg)
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Mercurial doesn't show it, but suppose the original text that both edits
|
||||
started with was 6; you added 1 and the other change added 2,
|
||||
so the correct answer might now be 9. First, edit the section
|
||||
Git doesn't show it, but suppose the original text that both edits
|
||||
started with was 1e8; you changed it to 1e10 and the other change to 1e9,
|
||||
so the correct answer might now be 1e10. First, edit the section
|
||||
to remove the markers and leave the correct code:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
VisitAll(visitor);
|
||||
if len(m) != 9 {
|
||||
t.Error("VisitAll misses some flags");
|
||||
arg = scale(arg)
|
||||
if arg > 1e10 {
|
||||
largeReduce(arg)
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Then ask Mercurial to mark the conflict as resolved:
|
||||
Then tell Git that the conflict is resolved by running
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ hg resolve -m flag_test.go
|
||||
$ git add sin.go
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
If you had been editing the file, say for debugging, but do not
|
||||
care to preserve your changes, you can run
|
||||
<code>hg revert flag_test.go</code> to abandon your
|
||||
changes, but you may still need to run
|
||||
<code>hg resolve -m</code> to mark the conflict resolved.
|
||||
<code>git</code> <code>reset</code> <code>HEAD</code> <code>sin.go</code>
|
||||
to abandon your changes.
|
||||
Then run <code>git</code> <code>rebase</code> <code>--continue</code> to
|
||||
restore the change commit.
|
||||
</p>
|
||||
|
||||
<h3>Reviewing code by others</h3>
|
||||
|
||||
<p>
|
||||
You can import a CL proposed by someone else into your local Mercurial client
|
||||
by using the <code>hg clpatch</code> command. Running
|
||||
You can import a change proposed by someone else into your local Git repository.
|
||||
On the Gerrit review page, click the "Download ▼" link in the upper right
|
||||
corner, copy the "Checkout" command and run it from your local Git repo.
|
||||
It should look something like this:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ hg clpatch 99999
|
||||
$ git fetch https://go.googlesource.com/review refs/changes/21/1221/1 && git checkout FETCH_HEAD
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
will apply the latest diff for CL 99999 to your working copy. If any of the
|
||||
files referenced in CL 99999 have local modifications, <code>clpatch</code>
|
||||
will refuse to apply the whole diff. Once applied, CL 99999 will show up in
|
||||
the output of <code>hg pending</code> and others.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To revert a CL you have applied locally, use the <code>hg revert</code>
|
||||
command. Running
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ hg revert @99999
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
will revert any files mentioned on CL 99999 to their original state. This can
|
||||
be an effective way of reverting one CL revision and applying another.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Once the CL has been submitted, the next time you run <code>hg sync</code>
|
||||
it will be removed from your local pending list. Occasionally the pending list
|
||||
can get out of sync leaving stale references to closed or abandoned CLs.
|
||||
You can use <code>hg change -D 99999</code> to remove the reference to CL 99999.
|
||||
To revert, change back to the branch you were working in.
|
||||
</p>
|
||||
|
||||
<h3>Submit the change after the review</h3>
|
||||
|
||||
<p>
|
||||
After the code has been <code>LGTM</code>'ed, it is time to submit
|
||||
it to the Mercurial repository.
|
||||
After the code has been <code>LGTM</code>'ed, an approver may
|
||||
submit it to the master branch using the Gerrit UI.
|
||||
There is a "Submit" button on the web page for the change
|
||||
that appears once the change is approved (marked +2).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you are not a committer, you cannot submit the change directly.
|
||||
Instead a committer, usually the reviewer who said <code>LGTM</code>,
|
||||
will run:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ hg clpatch 99999
|
||||
$ hg submit 99999
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The <code>submit</code> command submits the code. You will be listed as the
|
||||
author, but the change message will also indicate who the committer was.
|
||||
Your local client will notice that the change has been submitted
|
||||
when you next run <code>hg sync</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you are a committer, you can run:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ hg submit 99999
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
This checks the change into the repository.
|
||||
The change description will include a link to the code review,
|
||||
and the code review will be updated with a link to the change
|
||||
in the repository.
|
||||
Since the method used to integrate the changes is "Cherry Pick",
|
||||
the commit hashes in the repository will be changed by
|
||||
the submit operation.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If your local copy of the repository is out of date,
|
||||
<code>hg submit</code> will refuse the change:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ hg submit 99999
|
||||
local repository out of date; must sync before submit
|
||||
</pre>
|
||||
|
||||
<h3>More information</h3>
|
||||
|
||||
<p>
|
||||
In addition to the information here, the Go community maintains a <a href="https://code.google.com/p/go-wiki/wiki/CodeReview">CodeReview</a> wiki page.
|
||||
In addition to the information here, the Go community maintains a <a href="https://golang.org/wiki/CodeReview">CodeReview</a> wiki page.
|
||||
Feel free to contribute to this page as you learn the review process.
|
||||
</p>
|
||||
|
||||
@@ -617,7 +614,8 @@ Feel free to contribute to this page as you learn the review process.
|
||||
|
||||
<p>Files in the Go repository don't list author names,
|
||||
both to avoid clutter and to avoid having to keep the lists up to date.
|
||||
Instead, your name will appear in the <a href="https://code.google.com/p/go/source/list">Mercurial change log</a>
|
||||
Instead, your name will appear in the
|
||||
<a href="https://golang.org/change">change log</a>
|
||||
and in the <a href="/CONTRIBUTORS"><code>CONTRIBUTORS</code></a> file
|
||||
and perhaps the <a href="/AUTHORS"><code>AUTHORS</code></a> file.
|
||||
</p>
|
||||
@@ -654,7 +652,7 @@ This rigmarole needs to be done only for your first submission.
|
||||
<p>Code that you contribute should use the standard copyright header:</p>
|
||||
|
||||
<pre>
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// 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.
|
||||
</pre>
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
}-->
|
||||
|
||||
<p>This page summarizes the changes between official stable releases of Go.
|
||||
The <a href="//code.google.com/p/go/source/list">Mercurial change log</a>
|
||||
has the full details.</p>
|
||||
The <a href="//golang.org/change">change log</a> has the full details.</p>
|
||||
|
||||
<p>To update to a specific release, use:</p>
|
||||
|
||||
@@ -13,6 +12,20 @@ hg pull
|
||||
hg update <i>tag</i>
|
||||
</pre>
|
||||
|
||||
<h2 id="go1.4">go1.4 (released 2014/12/10)</h2>
|
||||
|
||||
<p>
|
||||
Go 1.4 is a major release of Go.
|
||||
Read the <a href="/doc/go1.4">Go 1.4 Release Notes</a> for more information.
|
||||
</p>
|
||||
|
||||
<h3 id="go1.4.minor">Minor revisions</h3>
|
||||
|
||||
<p>
|
||||
go1.4.1 (released 2015/01/15) includes bug fixes to the linker and the <code>log</code>, <code>syscall</code>, and <code>runtime</code> packages.
|
||||
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.4.1">Go 1.4.1 milestone on our issue tracker</a> for details.
|
||||
</p>
|
||||
|
||||
<h2 id="go1.3">go1.3 (released 2014/06/18)</h2>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<p>This page summarizes the changes between tagged weekly snapshots of Go.
|
||||
Such snapshots are no longer created. This page remains as a historical reference only.</p>
|
||||
|
||||
<p>For recent information, see the <a href="//code.google.com/p/go/source/list">Mercurial change log</a> and <a href="//groups.google.com/group/golang-dev/">development mailing list</a>.</p>
|
||||
<p>For recent information, see the <a href="//golang.org/change">change log</a> and <a href="//groups.google.com/group/golang-dev/">development mailing list</a>.</p>
|
||||
|
||||
<h2 id="2012-03-27">2012-03-27 (<a href="release.html#go1">Go 1</a>)</h2>
|
||||
|
||||
|
||||
@@ -298,7 +298,7 @@ For example,
|
||||
<h3 id="godoc">Changes to godoc</h3>
|
||||
<p>
|
||||
When invoked with the <code>-analysis</code> flag,
|
||||
<a href="//godoc.org/code.google.com/p/go.tools/cmd/godoc">godoc</a>
|
||||
<a href="//godoc.org/golang.org/x/tools/cmd/godoc">godoc</a>
|
||||
now performs sophisticated <a href="/lib/godoc/analysis/help.html">static
|
||||
analysis</a> of the code it indexes.
|
||||
The results of analysis are presented in both the source view and the
|
||||
@@ -318,7 +318,7 @@ call sites and their callees.
|
||||
The program <code>misc/benchcmp</code> that compares
|
||||
performance across benchmarking runs has been rewritten.
|
||||
Once a shell and awk script in the main repository, it is now a Go program in the <code>go.tools</code> repo.
|
||||
Documentation is <a href="//godoc.org/code.google.com/p/go.tools/cmd/benchcmp">here</a>.
|
||||
Documentation is <a href="//godoc.org/golang.org/x/tools/cmd/benchcmp">here</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
138
doc/go1.4.html
138
doc/go1.4.html
@@ -7,10 +7,16 @@
|
||||
<h2 id="introduction">Introduction to Go 1.4</h2>
|
||||
|
||||
<p>
|
||||
The latest Go release, version 1.4, arrives as scheduled six months after 1.3
|
||||
and contains only one tiny language change,
|
||||
a possibly breaking change to the compiler,
|
||||
a backwards-compatible simple form of <code>for</code>-<code>range</code> loop.
|
||||
The latest Go release, version 1.4, arrives as scheduled six months after 1.3.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It contains only one tiny language change,
|
||||
in the form of a backwards-compatible simple variant of <code>for</code>-<code>range</code> loop,
|
||||
and a possibly breaking change to the compiler involving methods on pointers-to-pointers.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The release focuses primarily on implementation work, improving the garbage collector
|
||||
and preparing the ground for a fully concurrent collector to be rolled out in the
|
||||
next few releases.
|
||||
@@ -20,7 +26,10 @@ this release therefore eliminates the notorious "hot stack split" problem.
|
||||
There are some new tools available including support in the <code>go</code> command
|
||||
for build-time source code generation.
|
||||
The release also adds support for ARM processors on Android and Native Client (NaCl)
|
||||
and AMD64 on Plan 9.
|
||||
and for AMD64 on Plan 9.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As always, Go 1.4 keeps the <a href="/doc/go1compat.html">promise
|
||||
of compatibility</a>,
|
||||
and almost everything
|
||||
@@ -35,7 +44,7 @@ Up until Go 1.3, <code>for</code>-<code>range</code> loop had two forms
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
for k, v := range x {
|
||||
for i, v := range x {
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
@@ -45,7 +54,7 @@ and
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
for k := range x {
|
||||
for i := range x {
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
@@ -120,9 +129,9 @@ compile but is easy to fix by adding an explicit dereference.
|
||||
<p>
|
||||
Go 1.4 can build binaries for ARM processors running the Android operating system.
|
||||
It can also build a <code>.so</code> library that can be loaded by an Android application
|
||||
using the supporting packages in the <a href="http://code.google.com/p/go.mobile">go.mobile</a> repository.
|
||||
using the supporting packages in the <a href="https://golang.org/x/mobile">mobile</a> subrepository.
|
||||
A brief description of the plans for this experimental port are available
|
||||
<a href="/s/go14android">here</a>.
|
||||
<a href="https://golang.org/s/go14android">here</a>.
|
||||
</p>
|
||||
|
||||
<h3 id="naclarm">NaCl on ARM</h3>
|
||||
@@ -172,7 +181,7 @@ of the documentation.
|
||||
<h3 id="runtime">Changes to the runtime</h3>
|
||||
|
||||
<p>
|
||||
Up to Go 1.4, the runtime (garbage collector, concurrency support, interface management,
|
||||
Prior to Go 1.4, the runtime (garbage collector, concurrency support, interface management,
|
||||
maps, slices, strings, ...) was mostly written in C, with some assembler support.
|
||||
In 1.4, much of the code has been translated to Go so that the garbage collector can scan
|
||||
the stacks of programs in the runtime and get accurate information about what variables
|
||||
@@ -193,13 +202,12 @@ A consequence is that stacks are no longer segmented, eliminating the "hot split
|
||||
When a stack limit is reached, a new, larger stack is allocated, all active frames for
|
||||
the goroutine are copied there, and any pointers into the stack are updated.
|
||||
Performance can be noticeably better in some cases and is always more predictable.
|
||||
Details are available in <a href="/s/contigstacks">the design document</a>.
|
||||
Details are available in <a href="https://golang.org/s/contigstacks">the design document</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The use of contiguous stacks means that stacks can start smaller without triggering performance issues,
|
||||
so the default starting size for a goroutine's stack in 1.4 has been reduced to 2048 bytes from 8192 bytes.
|
||||
TODO: It may be bumped to 4096 for the release.
|
||||
so the default starting size for a goroutine's stack in 1.4 has been reduced from 8192 bytes to 2048 bytes.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -320,7 +328,7 @@ from 1.5 and onward it will be enforced for any repository.
|
||||
|
||||
<p>
|
||||
Full details of the mechanism are in
|
||||
<a href="http://golang.org/s/go14internal">the design document</a>.
|
||||
<a href="https://golang.org/s/go14internal">the design document</a>.
|
||||
</p>
|
||||
|
||||
<h3 id="canonicalimports">Canonical import paths</h3>
|
||||
@@ -382,7 +390,25 @@ The new <code>-f</code> flag overrides this check.
|
||||
|
||||
<p>
|
||||
Further information is in
|
||||
<a href="http://golang.org/s/go14customimport">the design document</a>.
|
||||
<a href="https://golang.org/s/go14customimport">the design document</a>.
|
||||
</p>
|
||||
|
||||
<h3 id="subrepo">Import paths for the subrepositories</h3>
|
||||
|
||||
<p>
|
||||
The Go project subrepositories (<code>code.google.com/p/go.tools</code> and so on)
|
||||
are now available under custom import paths replacing <code>code.google.com/p/go.</code> with <code>golang.org/x/</code>,
|
||||
as in <code>golang.org/x/tools</code>.
|
||||
We will add canonical import comments to the code around June 1, 2015,
|
||||
at which point Go 1.4 and later will stop accepting the old <code>code.google.com</code> paths.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<em>Updating</em>: All code that imports from subrepositories should change
|
||||
to use the new <code>golang.org</code> paths.
|
||||
Go 1.0 and later can resolve and import the new paths, so updating will not break
|
||||
compatibility with older releases.
|
||||
Code that has not updated will stop compiling with Go 1.4 around June 1, 2015.
|
||||
</p>
|
||||
|
||||
<h3 id="gogenerate">The go generate subcommand</h3>
|
||||
@@ -394,13 +420,13 @@ to automate the running of tools to generate source code before compilation.
|
||||
For example, it can be used to run the <a href="/cmd/yacc"><code>yacc</code></a>
|
||||
compiler-compiler on a <code>.y</code> file to produce the Go source file implementing the grammar,
|
||||
or to automate the generation of <code>String</code> methods for typed constants using the new
|
||||
<a href="http://godoc.org/code.google.com/p/go.tools/cmd/stringer">stringer</a>
|
||||
tool in the <code>go.tools</code> repository.
|
||||
<a href="http://godoc.org/golang.org/x/tools/cmd/stringer">stringer</a>
|
||||
tool in the <code>golang.org/x/tools</code> subrepository.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For more information, see the
|
||||
<a href="http://golang.org/s/go1.4-generate">design document</a>.
|
||||
<a href="https://golang.org/s/go1.4-generate">design document</a>.
|
||||
</p>
|
||||
|
||||
<h3 id="filenames">Change to file name handling</h3>
|
||||
@@ -480,7 +506,7 @@ rebuild the standard library and commands, to avoid overwriting the installation
|
||||
<p>
|
||||
In the main Go source repository, the source code for the packages was kept in
|
||||
the directory <code>src/pkg</code>, which made sense but differed from
|
||||
other repositories, including the Go sub-repositories such as <code>go.tools</code>.
|
||||
other repositories, including the Go subrepositories.
|
||||
In Go 1.4, the<code> pkg</code> level of the source tree is now gone, so for example
|
||||
the <a href="/pkg/fmt/"><code>fmt</code></a> package's source, once kept in
|
||||
directory <code>src/pkg/fmt</code>, now lives one level higher in <code>src/fmt</code>.
|
||||
@@ -496,10 +522,7 @@ have been updated.
|
||||
<h3 id="swig">SWIG</h3>
|
||||
|
||||
<p>
|
||||
Due to the runtime changes in this release, Go 1.4 will require SWIG 3.0.3.
|
||||
At time of writing that has not yet been released, but we expect it to be by
|
||||
Go 1.4's release date.
|
||||
TODO
|
||||
Due to runtime changes in this release, Go 1.4 requires SWIG 3.0.3.
|
||||
</p>
|
||||
|
||||
<h3 id="misc">Miscellany</h3>
|
||||
@@ -518,7 +541,7 @@ editor, even for editors we do not use.
|
||||
The Go community at large is much better suited to managing this information.
|
||||
In Go 1.4, therefore, this support has been removed from the repository.
|
||||
Instead, there is a curated, informative list of what's available on
|
||||
a <a href="https://code.google.com/p/go-wiki/wiki/IDEsAndTextEditorPlugins">wiki page</a>.
|
||||
a <a href="//golang.org/wiki/IDEsAndTextEditorPlugins">wiki page</a>.
|
||||
</p>
|
||||
|
||||
<h2 id="performance">Performance</h2>
|
||||
@@ -586,19 +609,19 @@ The <a href="/pkg/syscall/"><code>syscall</code></a> package is now frozen excep
|
||||
for changes needed to maintain the core repository.
|
||||
In particular, it will no longer be extended to support new or different system calls
|
||||
that are not used by the core.
|
||||
The reasons are described at length in <a href="http://golang.org/s/go1.4-syscall">a
|
||||
The reasons are described at length in <a href="https://golang.org/s/go1.4-syscall">a
|
||||
separate document</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A new subrepository, <a href="http://code.google.com/p/go.sys">go.sys</a>,
|
||||
A new subrepository, <a href="https://golang.org/x/sys">golang.org/x/sys</a>,
|
||||
has been created to serve as the location for new developments to support system
|
||||
calls on all kernels.
|
||||
It has a nicer structure, with three packages that each hold the implementation of
|
||||
system calls for one of
|
||||
<a href="http://godoc.org/code.google.com/p/go.sys/unix">Unix</a>,
|
||||
<a href="http://godoc.org/code.google.com/p/go.sys/windows">Windows</a> and
|
||||
<a href="http://godoc.org/code.google.com/p/go.sys/plan9">Plan 9</a>.
|
||||
<a href="http://godoc.org/golang.org/x/sys/unix">Unix</a>,
|
||||
<a href="http://godoc.org/golang.org/x/sys/windows">Windows</a> and
|
||||
<a href="http://godoc.org/golang.org/x/sys/plan9">Plan 9</a>.
|
||||
These packages will be curated more generously, accepting all reasonable changes
|
||||
that reflect kernel interfaces in those operating systems.
|
||||
See the documentation and the article mentioned above for more information.
|
||||
@@ -608,7 +631,7 @@ See the documentation and the article mentioned above for more information.
|
||||
<em>Updating</em>: Existing programs are not affected as the <code>syscall</code>
|
||||
package is largely unchanged from the 1.3 release.
|
||||
Future development that requires system calls not in the <code>syscall</code> package
|
||||
should build on <code>go.sys</code> instead.
|
||||
should build on <code>golang.org/x/sys</code> instead.
|
||||
</p>
|
||||
|
||||
<h3 id="minor_library_changes">Minor changes to the library</h3>
|
||||
@@ -620,12 +643,29 @@ See the relevant package documentation for more information about each change.
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
The <a href="/pkg/archive/zip/"><code>archive/zip</code></a> package's
|
||||
<a href="/pkg/archive/zip/#Writer"><code>Writer</code></a> now supports a
|
||||
<a href="/pkg/archive/zip/#Writer.Flush"><code>Flush</code></a> method.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
The <a href="/pkg/compress/flate/"><code>compress/flate</code></a>,
|
||||
<a href="/pkg/compress/gzip/"><code>compress/gzip</code></a>,
|
||||
and <a href="/pkg/compress/zlib/"><code>compress/zlib</code></a>
|
||||
packages now support a <code>Reset</code> method
|
||||
for the decompressors, allowing them to reuse buffers and improve performance.
|
||||
The <a href="/pkg/compress/gzip/"><code>compress/gzip</code></a> package also has a
|
||||
<a href="/pkg/compress/gzip/#Reader.Multistream"><code>Multistream</code></a> method to control support
|
||||
for multistream files.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
The <a href="/pkg/crypto/"><code>crypto</code></a> package now has a
|
||||
<a href="/pkg/crypto/#Signer"><code>Signer</code></a> interface, implemented by the
|
||||
<code>PrivateKey</code> types in
|
||||
<a href="/pkg/crypto/ecdsa"><code>crypto/ecdsa</code></a> and
|
||||
<a href="/pkg/crypto/rsa"><code>crypto/rsa</code></a>.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
@@ -648,6 +688,16 @@ to help clients detect fallback attacks.
|
||||
those attacks.)
|
||||
</li>
|
||||
|
||||
<li>
|
||||
The <a href="/pkg/database/sql/"><code>database/sql</code></a> package can now list all registered
|
||||
<a href="/pkg/database/sql/#Drivers"><code>Drivers</code></a>.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
The <a href="/pkg/debug/dwarf/"><code>debug/dwarf</code></a> package now supports
|
||||
<a href="/pkg/debug/dwarf/#UnspecifiedType"><code>UnspecifiedType</code></a>s.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
In the <a href="/pkg/encoding/asn1/"><code>encoding/asn1</code></a> package,
|
||||
optional elements with a default value will now only be omitted if they have that value.
|
||||
@@ -668,6 +718,11 @@ in some cases, especially involving arrays, it can be faster.
|
||||
There is no functional change.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
The <a href="/pkg/encoding/xml/"><code>encoding/xml</code></a> package's
|
||||
<a href="/pkg/encoding/xml/#Decoder"><code>Decoder</code></a> can now report its input offset.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
In the <a href="/pkg/fmt/"><code>fmt</code></a> package,
|
||||
formatting of pointers to maps has changed to be consistent with that of pointers
|
||||
@@ -676,6 +731,28 @@ For instance, <code>&map[string]int{"one":</code> <code>1}</code> now prints
|
||||
<code>&map[one:</code> <code>1]</code> rather than as a hexadecimal pointer value.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
The <a href="/pkg/image/"><code>image</code></a> package's
|
||||
<a href="/pkg/image/#Image"><code>Image</code></a>
|
||||
implementations like
|
||||
<a href="/pkg/image/#RGBA"><code>RGBA</code></a> and
|
||||
<a href="/pkg/image/#Gray"><code>Gray</code></a> have specialized
|
||||
<a href="/pkg/image/#RGBA.RGBAAt"><code>RGBAAt</code></a> and
|
||||
<a href="/pkg/image/#Gray.GrayAt"><code>GrayAt</code></a> methods alongside the general
|
||||
<a href="/pkg/image/#Image.At"><code>At</code></a> method.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
The <a href="/pkg/image/png/"><code>image/png</code></a> package now has an
|
||||
<a href="/pkg/image/png/#Encoder"><code>Encoder</code></a>
|
||||
type to control the compression level used for encoding.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
The <a href="/pkg/math/"><code>math</code></a> package now has a
|
||||
<a href="/pkg/math/#Nextafter32"><code>Nextafter32</code><a/> function.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
The <a href="/pkg/net/http/"><code>net/http</code></a> package's
|
||||
<a href="/pkg/net/http/#Request"><code>Request</code></a> type
|
||||
@@ -704,6 +781,7 @@ The <a href="/pkg/os/"><code>os</code></a> package
|
||||
now implements symbolic links on the Windows operating system
|
||||
through the <a href="/pkg/os/#Symlink"><code>Symlink</code></a> function.
|
||||
Other operating systems already have this functionality.
|
||||
There is also a new <a href="/pkg/os/#Unsetenv"><code>Unsetenv</code></a> function.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
@@ -153,7 +153,7 @@ developed software based on Go 1.
|
||||
|
||||
<p>
|
||||
Code in sub-repositories of the main go tree, such as
|
||||
<a href="//code.google.com/p/go.net">code.google.com/p/go.net</a>,
|
||||
<a href="//golang.org/x/net">golang.org/x/net</a>,
|
||||
may be developed under
|
||||
looser compatibility requirements. However, the sub-repositories
|
||||
will be tagged as appropriate to identify versions that are compatible
|
||||
@@ -170,9 +170,9 @@ is therefore outside the purview of the guarantees made here.
|
||||
As of Go version 1.4, the <code>syscall</code> package is frozen.
|
||||
Any evolution of the system call interface must be supported elsewhere,
|
||||
such as in the
|
||||
<a href="http://godoc.org/code.google.com/p/go.sys">go.sys</a> subrepository.
|
||||
<a href="//golang.org/x/sys">go.sys</a> subrepository.
|
||||
For details and background, see
|
||||
<a href="https://golang.org/s/go1.4-syscall">this document</a>.
|
||||
<a href="//golang.org/s/go1.4-syscall">this document</a>.
|
||||
</p>
|
||||
|
||||
<h2 id="tools">Tools</h2>
|
||||
|
||||
@@ -228,7 +228,7 @@ document server running in a production configuration on
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Other examples include the <a href="https://code.google.com/p/vitess/">Vitess</a>
|
||||
Other examples include the <a href="//code.google.com/p/vitess/">Vitess</a>
|
||||
system for large-scale SQL installations and Google's download server, <code>dl.google.com</code>,
|
||||
which delivers Chrome binaries and other large installables such as <code>apt-get</code>
|
||||
packages.
|
||||
@@ -986,32 +986,6 @@ See the document
|
||||
for more information about how to proceed.
|
||||
</p>
|
||||
|
||||
<h3 id="Why_does_the_project_use_Mercurial_and_not_git">
|
||||
Why does the project use Mercurial and not git?</h3>
|
||||
|
||||
<p>
|
||||
The Go project, hosted by Google Code at
|
||||
<a href="//code.google.com/p/go">code.google.com/p/go</a>,
|
||||
uses Mercurial as its version control system.
|
||||
When the project launched,
|
||||
Google Code supported only Subversion and Mercurial.
|
||||
Mercurial was a better choice because of its plugin mechanism
|
||||
that allowed us to create the "codereview" plugin to connect
|
||||
the project to the excellent code review tools at
|
||||
<a href="//codereview.appspot.com">codereview.appspot.com</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Programmers who work
|
||||
with the Go project's source rather than release downloads sometimes
|
||||
ask for the project to switch to git.
|
||||
That would be possible, but it would be a lot of work and
|
||||
would also require reimplementing the codereview plugin.
|
||||
Given that Mercurial works today, with code review support,
|
||||
combined with the Go project's mostly linear, non-branching use of
|
||||
version control, a switch to git doesn't seem worthwhile.
|
||||
</p>
|
||||
|
||||
<h3 id="git_https">
|
||||
Why does "go get" use HTTPS when cloning a repository?</h3>
|
||||
|
||||
@@ -1616,7 +1590,7 @@ Go is a
|
||||
fine language in which to implement a self-hosting compiler: a native lexer and
|
||||
parser are already available in the <a href="/pkg/go/"><code>go</code></a> package
|
||||
and a separate type checking
|
||||
<a href="http://godoc.org/code.google.com/p/go.tools/go/types">package</a>
|
||||
<a href="http://godoc.org/golang.org/x/tools/go/types">package</a>
|
||||
has also been written.
|
||||
</p>
|
||||
|
||||
@@ -1715,7 +1689,7 @@ func main() {
|
||||
|
||||
<p>
|
||||
Nowadays, most Go programmers use a tool,
|
||||
<a href="http://godoc.org/code.google.com/p/go.tools/cmd/goimports">goimports</a>,
|
||||
<a href="http://godoc.org/golang.org/x/tools/cmd/goimports">goimports</a>,
|
||||
which automatically rewrites a Go source file to have the correct imports,
|
||||
eliminating the unused imports issue in practice.
|
||||
This program is easily connected to most editors to run automatically when a Go source file is written.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!--{
|
||||
"Title": "The Go Programming Language Specification",
|
||||
"Subtitle": "Version of October 27, 2014",
|
||||
"Subtitle": "Version of November 11, 2014",
|
||||
"Path": "/ref/spec"
|
||||
}-->
|
||||
|
||||
@@ -2521,30 +2521,40 @@ The following rules apply to selectors:
|
||||
<ol>
|
||||
<li>
|
||||
For a value <code>x</code> of type <code>T</code> or <code>*T</code>
|
||||
where <code>T</code> is not an interface type,
|
||||
where <code>T</code> is not a pointer or interface type,
|
||||
<code>x.f</code> denotes the field or method at the shallowest depth
|
||||
in <code>T</code> where there
|
||||
is such an <code>f</code>.
|
||||
If there is not exactly <a href="#Uniqueness_of_identifiers">one <code>f</code></a>
|
||||
with shallowest depth, the selector expression is illegal.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
For a variable <code>x</code> of type <code>I</code> where <code>I</code>
|
||||
For a value <code>x</code> of type <code>I</code> where <code>I</code>
|
||||
is an interface type, <code>x.f</code> denotes the actual method with name
|
||||
<code>f</code> of the value assigned to <code>x</code>.
|
||||
<code>f</code> of the dynamic value of <code>x</code>.
|
||||
If there is no method with name <code>f</code> in the
|
||||
<a href="#Method_sets">method set</a> of <code>I</code>, the selector
|
||||
expression is illegal.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
As an exception, if the type of <code>x</code> is a named pointer type
|
||||
and <code>(*x).f</code> is a valid selector expression denoting a field
|
||||
(but not a method), <code>x.f</code> is shorthand for <code>(*x).f</code>.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
In all other cases, <code>x.f</code> is illegal.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
If <code>x</code> is of pointer type and has the value
|
||||
<code>nil</code> and <code>x.f</code> denotes a struct field,
|
||||
assigning to or evaluating <code>x.f</code>
|
||||
causes a <a href="#Run_time_panics">run-time panic</a>.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
If <code>x</code> is of interface type and has the value
|
||||
<code>nil</code>, <a href="#Calls">calling</a> or
|
||||
@@ -2553,18 +2563,6 @@ causes a <a href="#Run_time_panics">run-time panic</a>.
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
Selectors automatically <a href="#Address_operators">dereference</a>
|
||||
pointers to structs.
|
||||
If <code>x</code> is a pointer to a struct, <code>x.y</code>
|
||||
is shorthand for <code>(*x).y</code>; if the field <code>y</code>
|
||||
is also a pointer to a struct, <code>x.y.z</code> is shorthand
|
||||
for <code>(*(*x).y).z</code>, and so on.
|
||||
If <code>x</code> contains an anonymous field of type <code>*A</code>,
|
||||
where <code>A</code> is also a struct type,
|
||||
<code>x.f</code> is shorthand for <code>(*x.A).f</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For example, given the declarations:
|
||||
</p>
|
||||
@@ -2574,13 +2572,13 @@ type T0 struct {
|
||||
x int
|
||||
}
|
||||
|
||||
func (recv *T0) M0()
|
||||
func (*T0) M0()
|
||||
|
||||
type T1 struct {
|
||||
y int
|
||||
}
|
||||
|
||||
func (recv T1) M1()
|
||||
func (T1) M1()
|
||||
|
||||
type T2 struct {
|
||||
z int
|
||||
@@ -2588,9 +2586,13 @@ type T2 struct {
|
||||
*T0
|
||||
}
|
||||
|
||||
func (recv *T2) M2()
|
||||
func (*T2) M2()
|
||||
|
||||
var p *T2 // with p != nil and p.T0 != nil
|
||||
type Q *T2
|
||||
|
||||
var t T2 // with t.T0 != nil
|
||||
var p *T2 // with p != nil and (*p).T0 != nil
|
||||
var q Q = p
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
@@ -2598,13 +2600,27 @@ one may write:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
p.z // (*p).z
|
||||
p.y // ((*p).T1).y
|
||||
p.x // (*(*p).T0).x
|
||||
t.z // t.z
|
||||
t.y // t.T1.y
|
||||
t.x // (*t.TO).x
|
||||
|
||||
p.M2() // (*p).M2()
|
||||
p.M1() // ((*p).T1).M1()
|
||||
p.M0() // ((*p).T0).M0()
|
||||
p.z // (*p).z
|
||||
p.y // (*p).T1.y
|
||||
p.x // (*(*p).T0).x
|
||||
|
||||
q.x // (*(*q).T0).x (*q).x is a valid field selector
|
||||
|
||||
p.M2() // p.M2() M2 expects *T2 receiver
|
||||
p.M1() // ((*p).T1).M1() M1 expects T1 receiver
|
||||
p.M0() // ((&(*p).T0)).M0() M0 expects *T0 receiver, see section on Calls
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
but the following is invalid:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
q.M0() // (*q).M0 is valid but not a field selector
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
BIN
doc/gopher/fiveyears.jpg
Normal file
BIN
doc/gopher/fiveyears.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 215 KiB |
@@ -24,7 +24,7 @@ Need help with Go? Try these resources.
|
||||
<p>
|
||||
Search the <a href="//groups.google.com/group/golang-nuts">golang-nuts</a>
|
||||
archives and consult the <a href="/doc/go_faq.html">FAQ</a> and
|
||||
<a href="//code.google.com/p/go-wiki/wiki">wiki</a> before posting.
|
||||
<a href="//golang.org/wiki">wiki</a> before posting.
|
||||
</p>
|
||||
|
||||
<h3 id="irc"><a href="irc:irc.freenode.net/go-nuts">Go IRC Channel</a></h3>
|
||||
|
||||
@@ -81,38 +81,21 @@ The full set of supported combinations is listed in the discussion of
|
||||
|
||||
<p>
|
||||
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>
|
||||
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="mercurial">Install Mercurial, if needed</h2>
|
||||
<h2 id="git">Install Git, if needed</h2>
|
||||
|
||||
<p>
|
||||
To perform the next step you must have Mercurial installed. (Check that you
|
||||
have an <code>hg</code> command.)
|
||||
To perform the next step you must have Git installed. (Check that you
|
||||
have a <code>git</code> command before proceeding.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you do not have a working Mercurial installation,
|
||||
If you do not have a working Git installation,
|
||||
follow the instructions on the
|
||||
<a href="http://mercurial.selenic.com/downloads">Mercurial downloads</a> page.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Mercurial versions 1.7.x and up require the configuration of
|
||||
<a href="http://mercurial.selenic.com/wiki/CACertificates">Certification Authorities</a>
|
||||
(CAs). Error messages of the form:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
warning: code.google.com certificate with fingerprint b1:af: ... bc not verified (check hostfingerprints or web.cacerts config setting)
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
when using Mercurial indicate that the CAs are missing.
|
||||
Check your Mercurial version (<code>hg --version</code>) and
|
||||
<a href="http://mercurial.selenic.com/wiki/CACertificates#Configuration_of_HTTPS_certificate_authorities">configure the CAs</a>
|
||||
if necessary.
|
||||
<a href="http://git-scm.com/downloads">Git downloads</a> page.
|
||||
</p>
|
||||
|
||||
|
||||
@@ -121,22 +104,24 @@ if necessary.
|
||||
<p>Go will install to a directory named <code>go</code>.
|
||||
Change to the directory that will be its parent
|
||||
and make sure the <code>go</code> directory does not exist.
|
||||
Then check out the repository:</p>
|
||||
Then clone the repository and check out the latest release tag:</p>
|
||||
|
||||
<pre>
|
||||
$ hg clone -u release https://code.google.com/p/go
|
||||
$ git clone https://go.googlesource.com/go
|
||||
$ cd go
|
||||
$ git checkout go1.4.1
|
||||
</pre>
|
||||
|
||||
<h2 id="head">(Optional) Switch to the default branch</h2>
|
||||
<h2 id="head">(Optional) Switch to the master branch</h2>
|
||||
|
||||
<p>If you intend to modify the go source code, and
|
||||
<a href="/doc/contribute.html">contribute your changes</a>
|
||||
to the project, then move your repository
|
||||
off the release branch, and onto the default (development) branch.
|
||||
off the release branch, and onto the master (development) branch.
|
||||
Otherwise, skip this step.</p>
|
||||
|
||||
<pre>
|
||||
$ hg update default
|
||||
$ git checkout master
|
||||
</pre>
|
||||
|
||||
<h2 id="install">Install Go</h2>
|
||||
@@ -241,12 +226,12 @@ provides <b>essential setup instructions</b> for using the Go tools.
|
||||
|
||||
<p>
|
||||
The source code for several Go tools (including <a href="/cmd/godoc/">godoc</a>)
|
||||
is kept in <a href="https://code.google.com/p/go.tools">the go.tools repository</a>.
|
||||
is kept in <a href="https://golang.org/x/tools">the go.tools repository</a>.
|
||||
To install all of them, run the <code>go</code> <code>get</code> command:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ go get code.google.com/p/go.tools/cmd/...
|
||||
$ go get golang.org/x/tools/cmd/...
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
@@ -254,12 +239,12 @@ Or if you just want to install a specific command (<code>godoc</code> in this ca
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
$ go get code.google.com/p/go.tools/cmd/godoc
|
||||
$ go get golang.org/x/tools/cmd/godoc
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
To install these tools, the <code>go</code> <code>get</code> command requires
|
||||
that <a href="#mercurial">Mercurial</a> be installed locally.
|
||||
that <a href="#git">Git</a> be installed locally.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -292,22 +277,18 @@ that receives a message summarizing each checkin to the Go repository.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Bugs can be reported using the <a href="//code.google.com/p/go/issues/list">Go issue tracker</a>.
|
||||
Bugs can be reported using the <a href="//golang.org/issue/new">Go issue tracker</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<h2 id="releases">Keeping up with releases</h2>
|
||||
|
||||
<p>
|
||||
The Go project maintains a stable tag in its Mercurial repository:
|
||||
<code>release</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The <code>release</code> tag refers to the current stable release of Go.
|
||||
Most Go users should use this version. New releases are announced on the
|
||||
New releases are announced on the
|
||||
<a href="//groups.google.com/group/golang-announce">golang-announce</a>
|
||||
mailing list.
|
||||
Each announcement mentions the latest release tag, for instance,
|
||||
<code>go1.4</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -316,11 +297,13 @@ To update an existing tree to the latest release, you can run:
|
||||
|
||||
<pre>
|
||||
$ cd go/src
|
||||
$ hg pull
|
||||
$ hg update release
|
||||
$ git fetch
|
||||
$ git checkout <i><tag></i>
|
||||
$ ./all.bash
|
||||
</pre>
|
||||
|
||||
Where <code><tag></code> is the version string of the release.
|
||||
|
||||
|
||||
<h2 id="environment">Optional environment variables</h2>
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ proceeding. If your OS or architecture is not on the list, it's possible that
|
||||
<tr><td>FreeBSD 8 or later</td> <td>amd64, 386, arm</td> <td>Debian GNU/kFreeBSD not supported; FreeBSD/ARM needs FreeBSD 10 or later</td></tr>
|
||||
<tr><td>Linux 2.6.23 or later with glibc</td> <td>amd64, 386, arm</td> <td>CentOS/RHEL 5.x not supported; no binary distribution for ARM yet</td></tr>
|
||||
<tr><td>Mac OS X 10.6 or later</td> <td>amd64, 386</td> <td>use the gcc<sup>†</sup> that comes with Xcode<sup>‡</sup></td></tr>
|
||||
<tr><td>Windows XP or later</td> <td>amd64, 386</td> <td>use MinGW gcc<sup>†</sup>. No need for cgywin or msys.</td></tr>
|
||||
<tr><td>Windows XP or later</td> <td>amd64, 386</td> <td>use MinGW gcc<sup>†</sup>. No need for cygwin or msys.</td></tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
|
||||
@@ -54,7 +54,7 @@ struct Addr
|
||||
{
|
||||
char sval[8];
|
||||
float64 dval;
|
||||
Prog* branch; // for 5g, 6g, 8g, 9g
|
||||
Prog* branch; // for 5g, 6g, 8g
|
||||
} u;
|
||||
|
||||
LSym* sym;
|
||||
@@ -62,9 +62,9 @@ struct Addr
|
||||
short type;
|
||||
uint8 index;
|
||||
int8 scale;
|
||||
int8 reg; // for 5l, 9l
|
||||
int8 name; // for 5l, 9l
|
||||
int8 class; // for 5l, 9l
|
||||
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
|
||||
@@ -89,13 +89,9 @@ struct Prog
|
||||
int32 lineno;
|
||||
Prog* link;
|
||||
short as;
|
||||
uchar scond; // arm only; condition codes
|
||||
|
||||
// operands
|
||||
uchar reg; // arm only
|
||||
uchar scond; // arm only
|
||||
Addr from;
|
||||
uchar reg; // arm, power64 only (e.g., ADD from, reg, to);
|
||||
// also used for ADATA width on arm, power64
|
||||
Addr from3; // power64 only (e.g., RLWM/FMADD from, reg, from3, to)
|
||||
Addr to;
|
||||
|
||||
// for 5g, 6g, 8g internal use
|
||||
@@ -107,11 +103,11 @@ struct Prog
|
||||
Prog* comefrom; // 6l, 8l
|
||||
Prog* pcrel; // 5l
|
||||
int32 spadj;
|
||||
uint16 mark;
|
||||
uint16 optab; // 5l, 9l
|
||||
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 */
|
||||
@@ -237,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,
|
||||
@@ -535,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);
|
||||
@@ -585,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);
|
||||
@@ -621,29 +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 linkpower64;
|
||||
extern LinkArch linkpower64le;
|
||||
|
||||
#pragma varargck type "A" int
|
||||
#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.
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
defaultcc: golang-codereviews@googlegroups.com
|
||||
contributors: http://go.googlecode.com/hg/CONTRIBUTORS
|
||||
|
||||
@@ -314,7 +314,11 @@ class CL(object):
|
||||
if self.name != "new":
|
||||
s = "code review %s: %s" % (self.name, s)
|
||||
typecheck(s, str)
|
||||
return branch_prefix(ui, repo) + s
|
||||
s = branch_prefix(ui, repo) + s
|
||||
# Rietveld does a hard reject on any subject > 100 chars. Be sure.
|
||||
if len(s) >= 100:
|
||||
s = s[0:95] + "..."
|
||||
return s
|
||||
|
||||
def Upload(self, ui, repo, send_mail=False, gofmt=True, gofmt_just_warn=False, creating=False, quiet=False):
|
||||
if not self.files and not creating:
|
||||
@@ -409,7 +413,7 @@ class CL(object):
|
||||
if not self.mailed:
|
||||
pmsg += "I'd like you to review this change to"
|
||||
branch = repo[None].branch()
|
||||
if branch.startswith("dev."):
|
||||
if workbranch(branch) and branch != "default":
|
||||
pmsg += " the " + branch + " branch of"
|
||||
pmsg += "\n" + repourl + "\n"
|
||||
else:
|
||||
@@ -1631,7 +1635,7 @@ def clpatch_or_undo(ui, repo, clname, opts, mode):
|
||||
try:
|
||||
cmd = subprocess.Popen(argv, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=None, close_fds=sys.platform != "win32")
|
||||
except:
|
||||
return "hgapplydiff: " + ExceptionDetail() + "\nInstall hgapplydiff with:\n$ go get code.google.com/p/go.codereview/cmd/hgapplydiff\n"
|
||||
return "hgapplydiff: " + ExceptionDetail() + "\nInstall hgapplydiff with:\n$ go get golang.org/x/codereview/cmd/hgapplydiff\n"
|
||||
|
||||
out, err = cmd.communicate(patch)
|
||||
if cmd.returncode != 0 and not opts["ignore_hgapplydiff_failure"]:
|
||||
@@ -1921,7 +1925,7 @@ def need_sync():
|
||||
def branch_prefix(ui, repo):
|
||||
prefix = ""
|
||||
branch = repo[None].branch()
|
||||
if branch.startswith("dev."):
|
||||
if workbranch(branch) and branch != "default":
|
||||
prefix = "[" + branch + "] "
|
||||
return prefix
|
||||
|
||||
@@ -2726,7 +2730,7 @@ def RietveldSetup(ui, repo):
|
||||
releaseBranch = t
|
||||
|
||||
def workbranch(name):
|
||||
return name == "default" or name.startswith('dev.')
|
||||
return name == "default" or name.startswith('dev.') or name == 'release-branch.go1.4'
|
||||
|
||||
#######################################################################
|
||||
# http://codereview.appspot.com/static/upload.py, heavily edited.
|
||||
@@ -3451,6 +3455,7 @@ class FakeMercurialUI(object):
|
||||
def __init__(self):
|
||||
self.quiet = True
|
||||
self.output = ''
|
||||
self.debugflag = False
|
||||
|
||||
def write(self, *args, **opts):
|
||||
self.output += ' '.join(args)
|
||||
@@ -3603,17 +3608,11 @@ class MercurialVCS(VersionControlSystem):
|
||||
if use_hg_shell:
|
||||
base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath], silent_ok=True)
|
||||
else:
|
||||
try:
|
||||
base_content = str(self.repo[base_rev][oldrelpath].data())
|
||||
except Exception:
|
||||
pass
|
||||
base_content = str(self.repo[base_rev][oldrelpath].data())
|
||||
is_binary = "\0" in base_content # Mercurial's heuristic
|
||||
if status != "R":
|
||||
try:
|
||||
new_content = open(relpath, "rb").read()
|
||||
is_binary = is_binary or "\0" in new_content
|
||||
except Exception:
|
||||
pass
|
||||
new_content = open(relpath, "rb").read()
|
||||
is_binary = is_binary or "\0" in new_content
|
||||
if is_binary and base_content and use_hg_shell:
|
||||
# Fetch again without converting newlines
|
||||
base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath],
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
# downloaded from the ICANN/IANA distribution.
|
||||
|
||||
# Versions to use.
|
||||
CODE=2014d
|
||||
DATA=2014d
|
||||
CODE=2014j
|
||||
DATA=2014j
|
||||
|
||||
set -e
|
||||
rm -rf work
|
||||
|
||||
Binary file not shown.
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo 'misc/benchcmp has moved:' >&2
|
||||
echo ' go get -u code.google.com/p/go.tools/cmd/benchcmp' >&2
|
||||
echo ' go get -u golang.org/x/tools/cmd/benchcmp' >&2
|
||||
exit 2
|
||||
|
||||
@@ -12,9 +12,15 @@ complex double complexDoubleSquared(complex double a) { return a*a; }
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func test8694(t *testing.T) {
|
||||
if runtime.GOARCH == "arm" {
|
||||
t.Skip("test8694 is disabled on ARM because 5l cannot handle thumb library.")
|
||||
}
|
||||
// Really just testing that this compiles, but check answer anyway.
|
||||
x := complex64(2 + 3i)
|
||||
x2 := x * x
|
||||
|
||||
@@ -1,33 +1,9 @@
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
typedef struct {} git_merge_file_input;
|
||||
|
||||
typedef struct {} git_merge_file_options;
|
||||
|
||||
void git_merge_file(
|
||||
git_merge_file_input *in,
|
||||
git_merge_file_options *opts) {}
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"./issue9026"
|
||||
)
|
||||
|
||||
func test9026(t *testing.T) {
|
||||
var in C.git_merge_file_input
|
||||
var opts *C.git_merge_file_options
|
||||
C.git_merge_file(&in, opts)
|
||||
|
||||
// Test that the generated type names are deterministic.
|
||||
// (Previously this would fail about 10% of the time.)
|
||||
//
|
||||
// Brittle: the assertion may fail spuriously when the algorithm
|
||||
// changes, but should remain stable otherwise.
|
||||
got := fmt.Sprintf("%T %T", in, opts)
|
||||
want := "cgotest._Ctype_struct___12 *cgotest._Ctype_struct___13"
|
||||
if got != want {
|
||||
t.Errorf("Non-deterministic type names: got %s, want %s", got, want)
|
||||
}
|
||||
}
|
||||
func test9026(t *testing.T) { issue9026.Test(t) }
|
||||
|
||||
36
misc/cgo/test/issue9026/issue9026.go
Normal file
36
misc/cgo/test/issue9026/issue9026.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package issue9026
|
||||
|
||||
// This file appears in its own package since the assertion tests the
|
||||
// per-package counter used to create fresh identifiers.
|
||||
|
||||
/*
|
||||
typedef struct {} git_merge_file_input;
|
||||
|
||||
typedef struct {} git_merge_file_options;
|
||||
|
||||
void git_merge_file(
|
||||
git_merge_file_input *in,
|
||||
git_merge_file_options *opts) {}
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
var in C.git_merge_file_input
|
||||
var opts *C.git_merge_file_options
|
||||
C.git_merge_file(&in, opts)
|
||||
|
||||
// Test that the generated type names are deterministic.
|
||||
// (Previously this would fail about 10% of the time.)
|
||||
//
|
||||
// Brittle: the assertion may fail spuriously when the algorithm
|
||||
// changes, but should remain stable otherwise.
|
||||
got := fmt.Sprintf("%T %T", in, opts)
|
||||
want := "issue9026._Ctype_struct___0 *issue9026._Ctype_struct___1"
|
||||
if got != want {
|
||||
t.Errorf("Non-deterministic type names: got %s, want %s", got, want)
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"compress/gzip"
|
||||
"crypto/sha1"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -30,7 +31,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"code.google.com/p/goauth2/oauth"
|
||||
storage "code.google.com/p/google-api-go-client/storage/v1beta2"
|
||||
storage "code.google.com/p/google-api-go-client/storage/v1"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -53,20 +54,20 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
blogPath = "code.google.com/p/go.blog"
|
||||
toolPath = "code.google.com/p/go.tools"
|
||||
blogPath = "golang.org/x/blog"
|
||||
toolPath = "golang.org/x/tools"
|
||||
tourPath = "code.google.com/p/go-tour"
|
||||
defaultToolTag = "release-branch.go1.3"
|
||||
defaultTourTag = "release-branch.go1.3"
|
||||
defaultToolTag = "release-branch.go1.4"
|
||||
defaultTourTag = "release-branch.go1.4"
|
||||
)
|
||||
|
||||
// Import paths for tool commands.
|
||||
// These must be the command that cmd/go knows to install to $GOROOT/bin
|
||||
// or $GOROOT/pkg/tool.
|
||||
var toolPaths = []string{
|
||||
"code.google.com/p/go.tools/cmd/cover",
|
||||
"code.google.com/p/go.tools/cmd/godoc",
|
||||
"code.google.com/p/go.tools/cmd/vet",
|
||||
"golang.org/x/tools/cmd/cover",
|
||||
"golang.org/x/tools/cmd/godoc",
|
||||
"golang.org/x/tools/cmd/vet",
|
||||
}
|
||||
|
||||
var preBuildCleanFiles = []string{
|
||||
@@ -504,16 +505,38 @@ func (b *Build) extras() error {
|
||||
}
|
||||
|
||||
func (b *Build) get(repoPath, revision string) error {
|
||||
// Fetch the packages (without building/installing).
|
||||
_, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"),
|
||||
"get", "-d", repoPath+"/...")
|
||||
if err != nil {
|
||||
return err
|
||||
dest := filepath.Join(b.gopath, "src", filepath.FromSlash(repoPath))
|
||||
|
||||
if strings.HasPrefix(repoPath, "golang.org/x/") {
|
||||
// For sub-repos, fetch the old Mercurial repo; bypass "go get".
|
||||
// DO NOT import this special case into the git tree.
|
||||
|
||||
if err := os.MkdirAll(filepath.Dir(dest), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
repo := strings.Replace(repoPath, "golang.org/x/", "https://code.google.com/p/go.", 1)
|
||||
if _, err := b.run(b.gopath, "hg", "clone", repo, dest); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Fetch the packages (without building/installing).
|
||||
_, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"),
|
||||
"get", "-d", repoPath+"/...")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Update the repo to the specified revision.
|
||||
p := filepath.Join(b.gopath, "src", filepath.FromSlash(repoPath))
|
||||
_, err = b.run(p, "hg", "update", revision)
|
||||
var err error
|
||||
switch {
|
||||
case exists(filepath.Join(dest, ".git")):
|
||||
_, err = b.run(dest, "git", "checkout", revision)
|
||||
case exists(filepath.Join(dest, ".hg")):
|
||||
_, err = b.run(dest, "hg", "update", revision)
|
||||
default:
|
||||
err = errors.New("unknown version control system")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,6 @@ go src=..
|
||||
gofmt_test.go
|
||||
testdata
|
||||
+
|
||||
link
|
||||
testdata
|
||||
+
|
||||
archive
|
||||
tar
|
||||
testdata
|
||||
|
||||
5100
misc/pprof
5100
misc/pprof
File diff suppressed because it is too large
Load Diff
@@ -36,6 +36,7 @@ type Scanner struct {
|
||||
start int // First non-processed byte in buf.
|
||||
end int // End of data in buf.
|
||||
err error // Sticky error.
|
||||
empties int // Count of successive empty tokens.
|
||||
}
|
||||
|
||||
// SplitFunc is the signature of the split function used to tokenize the
|
||||
@@ -108,6 +109,8 @@ func (s *Scanner) Text() string {
|
||||
// After Scan returns false, the Err method will return any error that
|
||||
// occurred during scanning, except that if it was io.EOF, Err
|
||||
// will return nil.
|
||||
// Split panics if the split function returns 100 empty tokens without
|
||||
// advancing the input. This is a common error mode for scanners.
|
||||
func (s *Scanner) Scan() bool {
|
||||
// Loop until we have a token.
|
||||
for {
|
||||
@@ -125,6 +128,15 @@ func (s *Scanner) Scan() bool {
|
||||
}
|
||||
s.token = token
|
||||
if token != nil {
|
||||
if s.err == nil || advance > 0 {
|
||||
s.empties = 0
|
||||
} else {
|
||||
// Returning tokens not advancing input at EOF.
|
||||
s.empties++
|
||||
if s.empties > 100 {
|
||||
panic("bufio.Scan: 100 empty tokens without progressing")
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -172,6 +184,7 @@ func (s *Scanner) Scan() bool {
|
||||
break
|
||||
}
|
||||
if n > 0 {
|
||||
s.empties = 0
|
||||
break
|
||||
}
|
||||
loop++
|
||||
|
||||
@@ -455,3 +455,70 @@ func TestEmptyTokens(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func loopAtEOFSplit(data []byte, atEOF bool) (advance int, token []byte, err error) {
|
||||
if len(data) > 0 {
|
||||
return 1, data[:1], nil
|
||||
}
|
||||
return 0, data, nil
|
||||
}
|
||||
|
||||
func TestDontLoopForever(t *testing.T) {
|
||||
s := NewScanner(strings.NewReader("abc"))
|
||||
s.Split(loopAtEOFSplit)
|
||||
// Expect a panic
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err == nil {
|
||||
t.Fatal("should have panicked")
|
||||
}
|
||||
if msg, ok := err.(string); !ok || !strings.Contains(msg, "empty tokens") {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
for count := 0; s.Scan(); count++ {
|
||||
if count > 1000 {
|
||||
t.Fatal("looping")
|
||||
}
|
||||
}
|
||||
if s.Err() != nil {
|
||||
t.Fatal("after scan:", s.Err())
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlankLines(t *testing.T) {
|
||||
s := NewScanner(strings.NewReader(strings.Repeat("\n", 1000)))
|
||||
for count := 0; s.Scan(); count++ {
|
||||
if count > 2000 {
|
||||
t.Fatal("looping")
|
||||
}
|
||||
}
|
||||
if s.Err() != nil {
|
||||
t.Fatal("after scan:", s.Err())
|
||||
}
|
||||
}
|
||||
|
||||
type countdown int
|
||||
|
||||
func (c *countdown) split(data []byte, atEOF bool) (advance int, token []byte, err error) {
|
||||
if *c > 0 {
|
||||
*c--
|
||||
return 1, data[:1], nil
|
||||
}
|
||||
return 0, nil, nil
|
||||
}
|
||||
|
||||
// Check that the looping-at-EOF check doesn't trigger for merely empty tokens.
|
||||
func TestEmptyLinesOK(t *testing.T) {
|
||||
c := countdown(10000)
|
||||
s := NewScanner(strings.NewReader(strings.Repeat("\n", 10000)))
|
||||
s.Split(c.split)
|
||||
for s.Scan() {
|
||||
}
|
||||
if s.Err() != nil {
|
||||
t.Fatal("after scan:", s.Err())
|
||||
}
|
||||
if c != 0 {
|
||||
t.Fatalf("stopped with %d left to process", c)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,6 @@ struct Sym
|
||||
int32 value;
|
||||
ushort type;
|
||||
char *name;
|
||||
char* labelname;
|
||||
char sym;
|
||||
};
|
||||
#define S ((Sym*)0)
|
||||
@@ -137,8 +136,6 @@ void newio(void);
|
||||
void newfile(char*, int);
|
||||
Sym* slookup(char*);
|
||||
Sym* lookup(void);
|
||||
Sym* labellookup(Sym*);
|
||||
void settext(LSym*);
|
||||
void syminit(Sym*);
|
||||
int32 yylex(void);
|
||||
int getc(void);
|
||||
|
||||
@@ -73,11 +73,15 @@ prog:
|
||||
line
|
||||
|
||||
line:
|
||||
LNAME ':'
|
||||
LLAB ':'
|
||||
{
|
||||
if($1->value != pc)
|
||||
yyerror("redeclaration of %s", $1->name);
|
||||
$1->value = pc;
|
||||
}
|
||||
line
|
||||
| LNAME ':'
|
||||
{
|
||||
$1 = labellookup($1);
|
||||
if($1->type == LLAB && $1->value != pc)
|
||||
yyerror("redeclaration of %s", $1->labelname);
|
||||
$1->type = LLAB;
|
||||
$1->value = pc;
|
||||
}
|
||||
@@ -214,21 +218,18 @@ inst:
|
||||
*/
|
||||
| LTYPEB name ',' imm
|
||||
{
|
||||
settext($2.sym);
|
||||
$4.type = D_CONST2;
|
||||
$4.offset2 = ArgsSizeUnknown;
|
||||
outcode($1, Always, &$2, 0, &$4);
|
||||
}
|
||||
| LTYPEB name ',' con ',' imm
|
||||
{
|
||||
settext($2.sym);
|
||||
$6.type = D_CONST2;
|
||||
$6.offset2 = ArgsSizeUnknown;
|
||||
outcode($1, Always, &$2, $4, &$6);
|
||||
}
|
||||
| LTYPEB name ',' con ',' imm '-' con
|
||||
{
|
||||
settext($2.sym);
|
||||
$6.type = D_CONST2;
|
||||
$6.offset2 = $8;
|
||||
outcode($1, Always, &$2, $4, &$6);
|
||||
@@ -372,10 +373,15 @@ rel:
|
||||
}
|
||||
| LNAME offset
|
||||
{
|
||||
$1 = labellookup($1);
|
||||
$$ = nullgen;
|
||||
if(pass == 2 && $1->type != LLAB)
|
||||
yyerror("undefined label: %s", $1->labelname);
|
||||
if(pass == 2)
|
||||
yyerror("undefined label: %s", $1->name);
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $2;
|
||||
}
|
||||
| LLAB offset
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $1->value + $2;
|
||||
}
|
||||
|
||||
2099
src/cmd/5a/y.tab.c
2099
src/cmd/5a/y.tab.c
File diff suppressed because it is too large
Load Diff
@@ -1,24 +1,21 @@
|
||||
/* A Bison parser, made by GNU Bison 2.3. */
|
||||
/* A Bison parser, made by GNU Bison 2.7.12-4996. */
|
||||
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
/* 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 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
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
|
||||
@@ -29,10 +26,20 @@
|
||||
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
|
||||
@@ -141,24 +148,41 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE
|
||||
#line 39 "a.y"
|
||||
{
|
||||
/* Line 2053 of yacc.c */
|
||||
#line 39 "a.y"
|
||||
|
||||
Sym *sym;
|
||||
int32 lval;
|
||||
double dval;
|
||||
char sval[8];
|
||||
Addr addr;
|
||||
}
|
||||
/* Line 1529 of yacc.c. */
|
||||
#line 157 "y.tab.h"
|
||||
YYSTYPE;
|
||||
|
||||
|
||||
/* 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
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
#ifdef YYPARSE_PARAM
|
||||
#if defined __STDC__ || defined __cplusplus
|
||||
int yyparse (void *YYPARSE_PARAM);
|
||||
#else
|
||||
int yyparse ();
|
||||
#endif
|
||||
#else /* ! YYPARSE_PARAM */
|
||||
#if defined __STDC__ || defined __cplusplus
|
||||
int yyparse (void);
|
||||
#else
|
||||
int yyparse ();
|
||||
#endif
|
||||
#endif /* ! YYPARSE_PARAM */
|
||||
|
||||
#endif /* !YY_YY_Y_TAB_H_INCLUDED */
|
||||
|
||||
@@ -86,7 +86,7 @@ datagostring(Strlit *sval, Addr *a)
|
||||
sym = stringsym(sval->s, sval->len);
|
||||
a->type = D_OREG;
|
||||
a->name = D_EXTERN;
|
||||
a->etype = TSTRING;
|
||||
a->etype = TINT32;
|
||||
a->offset = 0; // header
|
||||
a->reg = NREG;
|
||||
a->sym = linksym(sym);
|
||||
|
||||
@@ -1353,10 +1353,9 @@ naddr(Node *n, Addr *a, int canemitcode)
|
||||
case OITAB:
|
||||
// itable of interface value
|
||||
naddr(n->left, a, canemitcode);
|
||||
a->etype = simtype[tptr];
|
||||
a->etype = TINT32;
|
||||
if(a->type == D_CONST && a->offset == 0)
|
||||
break; // len(nil)
|
||||
a->width = widthptr;
|
||||
break;
|
||||
|
||||
case OSPTR:
|
||||
|
||||
@@ -63,8 +63,8 @@ enum
|
||||
|
||||
uint32 BLOAD(Reg*);
|
||||
uint32 BSTORE(Reg*);
|
||||
uint64 LOAD(Reg*);
|
||||
uint64 STORE(Reg*);
|
||||
uint32 LOAD(Reg*);
|
||||
uint32 STORE(Reg*);
|
||||
*/
|
||||
|
||||
// A Reg is a wrapper around a single Prog (one instruction) that holds
|
||||
@@ -75,18 +75,12 @@ struct Reg
|
||||
{
|
||||
Flow f;
|
||||
|
||||
Bits set; // regopt variables written by this instruction.
|
||||
Bits use1; // regopt variables read by prog->from.
|
||||
Bits use2; // regopt variables read by prog->to.
|
||||
Bits set; // variables written by this instruction.
|
||||
Bits use1; // variables read by prog->from.
|
||||
Bits use2; // variables read by prog->to.
|
||||
|
||||
// refahead/refbehind are the regopt variables whose current
|
||||
// value may be used in the following/preceding instructions
|
||||
// up to a CALL (or the value is clobbered).
|
||||
Bits refbehind;
|
||||
Bits refahead;
|
||||
// calahead/calbehind are similar, but for variables in
|
||||
// instructions that are reachable after hitting at least one
|
||||
// CALL.
|
||||
Bits calbehind;
|
||||
Bits calahead;
|
||||
Bits regdiff;
|
||||
@@ -99,16 +93,6 @@ struct Reg
|
||||
|
||||
#define NRGN 600
|
||||
/*c2go enum { NRGN = 600 }; */
|
||||
|
||||
// A Rgn represents a single regopt variable over a region of code
|
||||
// where a register could potentially be dedicated to that variable.
|
||||
// The code encompassed by a Rgn is defined by the flow graph,
|
||||
// starting at enter, flood-filling forward while varno is refahead
|
||||
// and backward while varno is refbehind, and following branches. A
|
||||
// single variable may be represented by multiple disjoint Rgns and
|
||||
// each Rgn may choose a different register for that variable.
|
||||
// Registers are allocated to regions greedily in order of descending
|
||||
// cost.
|
||||
struct Rgn
|
||||
{
|
||||
Reg* enter;
|
||||
@@ -160,8 +144,8 @@ void prop(Reg*, Bits, Bits);
|
||||
void synch(Reg*, Bits);
|
||||
uint32 allreg(uint32, Rgn*);
|
||||
void paint1(Reg*, int);
|
||||
uint32 paint2(Reg*, int, int);
|
||||
void paint3(Reg*, int, uint32, int);
|
||||
uint32 paint2(Reg*, int);
|
||||
void paint3(Reg*, int, int32, int);
|
||||
void addreg(Adr*, int);
|
||||
void dumpit(char *str, Flow *r0, int);
|
||||
|
||||
@@ -172,10 +156,10 @@ void peep(Prog*);
|
||||
void excise(Flow*);
|
||||
int copyu(Prog*, Adr*, Adr*);
|
||||
|
||||
uint32 RtoB(int);
|
||||
uint32 FtoB(int);
|
||||
int BtoR(uint32);
|
||||
int BtoF(uint32);
|
||||
int32 RtoB(int);
|
||||
int32 FtoB(int);
|
||||
int BtoR(int32);
|
||||
int BtoF(int32);
|
||||
|
||||
/*
|
||||
* prog.c
|
||||
@@ -203,16 +187,16 @@ enum
|
||||
SizeF = 1<<7, // float aka float32
|
||||
SizeD = 1<<8, // double aka float64
|
||||
|
||||
// Left side (Prog.from): address taken, read, write.
|
||||
// Left side: address taken, read, write.
|
||||
LeftAddr = 1<<9,
|
||||
LeftRead = 1<<10,
|
||||
LeftWrite = 1<<11,
|
||||
|
||||
// Register in middle (Prog.reg); only ever read.
|
||||
// Register in middle; never written.
|
||||
RegRead = 1<<12,
|
||||
CanRegRead = 1<<13,
|
||||
|
||||
// Right side (Prog.to): address taken, read, write.
|
||||
// Right side: address taken, read, write.
|
||||
RightAddr = 1<<14,
|
||||
RightRead = 1<<15,
|
||||
RightWrite = 1<<16,
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "opt.h"
|
||||
|
||||
#define NREGVAR 32
|
||||
#define REGBITS ((uint64)0xffffffffull)
|
||||
#define REGBITS ((uint32)0xffffffff)
|
||||
/*c2go enum {
|
||||
NREGVAR = 32,
|
||||
REGBITS = 0xffffffff,
|
||||
@@ -86,7 +86,7 @@ setaddrs(Bits bit)
|
||||
i = bnum(bit);
|
||||
node = var[i].node;
|
||||
n = var[i].name;
|
||||
biclr(&bit, i);
|
||||
bit.b[i/32] &= ~(1L<<(i%32));
|
||||
|
||||
// disable all pieces of that variable
|
||||
for(i=0; i<nvar; i++) {
|
||||
@@ -199,7 +199,7 @@ regopt(Prog *firstp)
|
||||
proginfo(&info, p);
|
||||
|
||||
// Avoid making variables for direct-called functions.
|
||||
if(p->as == ABL && p->to.type == D_EXTERN)
|
||||
if(p->as == ABL && p->to.name == D_EXTERN)
|
||||
continue;
|
||||
|
||||
bit = mkvar(r, &p->from);
|
||||
@@ -230,7 +230,7 @@ regopt(Prog *firstp)
|
||||
|
||||
/* the mod/div runtime routines smash R12 */
|
||||
if(p->as == ADIV || p->as == ADIVU || p->as == AMOD || p->as == AMODU)
|
||||
r->set.b[z] |= RtoB(12);
|
||||
r->set.b[0] |= RtoB(12);
|
||||
}
|
||||
if(firstr == R)
|
||||
return;
|
||||
@@ -393,7 +393,7 @@ loop2:
|
||||
for(z=0; z<BITS; z++)
|
||||
bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
|
||||
~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
|
||||
if(bany(&bit) && !r->f.refset) {
|
||||
if(bany(&bit) & !r->f.refset) {
|
||||
// should never happen - all variables are preset
|
||||
if(debug['w'])
|
||||
print("%L: used and not set: %Q\n", r->f.prog->lineno, bit);
|
||||
@@ -425,7 +425,7 @@ loop2:
|
||||
if(debug['R'] > 1)
|
||||
print("\n");
|
||||
paint1(r, i);
|
||||
biclr(&bit, i);
|
||||
bit.b[i/32] &= ~(1L<<(i%32));
|
||||
if(change <= 0) {
|
||||
if(debug['R'])
|
||||
print("%L $%d: %Q\n",
|
||||
@@ -454,13 +454,9 @@ brk:
|
||||
* replace code (paint3)
|
||||
*/
|
||||
rgp = region;
|
||||
if(debug['R'] && debug['v'])
|
||||
print("\nregisterizing\n");
|
||||
for(i=0; i<nregion; i++) {
|
||||
if(debug['R'] && debug['v'])
|
||||
print("region %d: cost %d varno %d enter %d\n", i, rgp->cost, rgp->varno, rgp->enter->f.prog->pc);
|
||||
bit = blsh(rgp->varno);
|
||||
vreg = paint2(rgp->enter, rgp->varno, 0);
|
||||
vreg = paint2(rgp->enter, rgp->varno);
|
||||
vreg = allreg(vreg, rgp);
|
||||
if(debug['R']) {
|
||||
if(rgp->regno >= NREG)
|
||||
@@ -481,6 +477,9 @@ brk:
|
||||
rgp++;
|
||||
}
|
||||
|
||||
if(debug['R'] && debug['v'])
|
||||
dumpit("pass6", &firstr->f, 1);
|
||||
|
||||
/*
|
||||
* free aux structures. peep allocates new ones.
|
||||
*/
|
||||
@@ -489,15 +488,6 @@ brk:
|
||||
flowend(g);
|
||||
firstr = R;
|
||||
|
||||
if(debug['R'] && debug['v']) {
|
||||
// Rebuild flow graph, since we inserted instructions
|
||||
g = flowstart(firstp, sizeof(Reg));
|
||||
firstr = (Reg*)g->start;
|
||||
dumpit("pass6", &firstr->f, 1);
|
||||
flowend(g);
|
||||
firstr = R;
|
||||
}
|
||||
|
||||
/*
|
||||
* pass 7
|
||||
* peep-hole on basic block
|
||||
@@ -580,7 +570,7 @@ walkvardef(Node *n, Reg *r, int active)
|
||||
break;
|
||||
for(v=n->opt; v!=nil; v=v->nextinnode) {
|
||||
bn = v - var;
|
||||
biset(&r1->act, bn);
|
||||
r1->act.b[bn/32] |= 1L << (bn%32);
|
||||
}
|
||||
if(r1->f.prog->as == ABL)
|
||||
break;
|
||||
@@ -616,7 +606,7 @@ addsplits(void)
|
||||
~(r->calahead.b[z] & addrs.b[z]);
|
||||
while(bany(&bit)) {
|
||||
i = bnum(bit);
|
||||
biclr(&bit, i);
|
||||
bit.b[i/32] &= ~(1L << (i%32));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -982,10 +972,10 @@ prop(Reg *r, Bits ref, Bits cal)
|
||||
for(z=0; z<BITS; z++) {
|
||||
if(cal.b[z] == 0)
|
||||
continue;
|
||||
for(i=0; i<64; i++) {
|
||||
if(z*64+i >= nvar || ((cal.b[z]>>i)&1) == 0)
|
||||
for(i=0; i<32; i++) {
|
||||
if(z*32+i >= nvar || ((cal.b[z]>>i)&1) == 0)
|
||||
continue;
|
||||
v = var+z*64+i;
|
||||
v = var+z*32+i;
|
||||
if(v->node->opt == nil) // v represents fixed register, not Go variable
|
||||
continue;
|
||||
|
||||
@@ -1001,10 +991,10 @@ prop(Reg *r, Bits ref, Bits cal)
|
||||
// This will set the bits at most twice, keeping the overall loop linear.
|
||||
v1 = v->node->opt;
|
||||
j = v1 - var;
|
||||
if(v == v1 || !btest(&cal, j)) {
|
||||
if(v == v1 || ((cal.b[j/32]>>(j&31))&1) == 0) {
|
||||
for(; v1 != nil; v1 = v1->nextinnode) {
|
||||
j = v1 - var;
|
||||
biset(&cal, j);
|
||||
cal.b[j/32] |= 1<<(j&31);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1125,10 +1115,10 @@ paint1(Reg *r, int bn)
|
||||
Reg *r1;
|
||||
Prog *p;
|
||||
int z;
|
||||
uint64 bb;
|
||||
uint32 bb;
|
||||
|
||||
z = bn/64;
|
||||
bb = 1LL<<(bn%64);
|
||||
z = bn/32;
|
||||
bb = 1L<<(bn%32);
|
||||
if(r->act.b[z] & bb)
|
||||
return;
|
||||
for(;;) {
|
||||
@@ -1199,14 +1189,14 @@ paint1(Reg *r, int bn)
|
||||
}
|
||||
|
||||
uint32
|
||||
paint2(Reg *r, int bn, int depth)
|
||||
paint2(Reg *r, int bn)
|
||||
{
|
||||
Reg *r1;
|
||||
int z;
|
||||
uint64 bb, vreg;
|
||||
uint32 bb, vreg;
|
||||
|
||||
z = bn/64;
|
||||
bb = 1LL << (bn%64);
|
||||
z = bn/32;
|
||||
bb = 1L << (bn%32);
|
||||
vreg = regbits;
|
||||
if(!(r->act.b[z] & bb))
|
||||
return vreg;
|
||||
@@ -1223,9 +1213,6 @@ paint2(Reg *r, int bn, int depth)
|
||||
r = r1;
|
||||
}
|
||||
for(;;) {
|
||||
if(debug['R'] && debug['v'])
|
||||
print(" paint2 %d %P\n", depth, r->f.prog);
|
||||
|
||||
r->act.b[z] &= ~bb;
|
||||
|
||||
vreg |= r->regu;
|
||||
@@ -1233,14 +1220,14 @@ paint2(Reg *r, int bn, int depth)
|
||||
if(r->refbehind.b[z] & bb)
|
||||
for(r1 = (Reg*)r->f.p2; r1 != R; r1 = (Reg*)r1->f.p2link)
|
||||
if(r1->refahead.b[z] & bb)
|
||||
vreg |= paint2(r1, bn, depth+1);
|
||||
vreg |= paint2(r1, bn);
|
||||
|
||||
if(!(r->refahead.b[z] & bb))
|
||||
break;
|
||||
r1 = (Reg*)r->f.s2;
|
||||
if(r1 != R)
|
||||
if(r1->refbehind.b[z] & bb)
|
||||
vreg |= paint2(r1, bn, depth+1);
|
||||
vreg |= paint2(r1, bn);
|
||||
r = (Reg*)r->f.s1;
|
||||
if(r == R)
|
||||
break;
|
||||
@@ -1253,15 +1240,15 @@ paint2(Reg *r, int bn, int depth)
|
||||
}
|
||||
|
||||
void
|
||||
paint3(Reg *r, int bn, uint32 rb, int rn)
|
||||
paint3(Reg *r, int bn, int32 rb, int rn)
|
||||
{
|
||||
Reg *r1;
|
||||
Prog *p;
|
||||
int z;
|
||||
uint64 bb;
|
||||
uint32 bb;
|
||||
|
||||
z = bn/64;
|
||||
bb = 1LL << (bn%64);
|
||||
z = bn/32;
|
||||
bb = 1L << (bn%32);
|
||||
if(r->act.b[z] & bb)
|
||||
return;
|
||||
for(;;) {
|
||||
@@ -1346,7 +1333,7 @@ addreg(Adr *a, int rn)
|
||||
* 10 R10
|
||||
* 12 R12
|
||||
*/
|
||||
uint32
|
||||
int32
|
||||
RtoB(int r)
|
||||
{
|
||||
if(r >= REGTMP-2 && r != 12) // excluded R9 and R10 for m and g, but not R12
|
||||
@@ -1355,10 +1342,8 @@ RtoB(int r)
|
||||
}
|
||||
|
||||
int
|
||||
BtoR(uint32 b)
|
||||
BtoR(int32 b)
|
||||
{
|
||||
// TODO Allow R0 and R1, but be careful with a 0 return
|
||||
// TODO Allow R9. Only R10 is reserved now (just g, not m).
|
||||
b &= 0x11fcL; // excluded R9 and R10 for m and g, but not R12
|
||||
if(b == 0)
|
||||
return 0;
|
||||
@@ -1372,7 +1357,7 @@ BtoR(uint32 b)
|
||||
* ... ...
|
||||
* 31 F15
|
||||
*/
|
||||
uint32
|
||||
int32
|
||||
FtoB(int f)
|
||||
{
|
||||
|
||||
@@ -1382,7 +1367,7 @@ FtoB(int f)
|
||||
}
|
||||
|
||||
int
|
||||
BtoF(uint32 b)
|
||||
BtoF(int32 b)
|
||||
{
|
||||
|
||||
b &= 0xfffc0000L;
|
||||
@@ -1457,14 +1442,12 @@ dumpit(char *str, Flow *r0, int isreg)
|
||||
print(" (only)");
|
||||
print("\n");
|
||||
}
|
||||
// Print successors if it's not just the next one
|
||||
if(r->s1 != r->link || r->s2 != nil) {
|
||||
print(" succ:");
|
||||
if(r->s1 != nil)
|
||||
print(" %.4ud", (int)r->s1->prog->pc);
|
||||
if(r->s2 != nil)
|
||||
print(" %.4ud", (int)r->s2->prog->pc);
|
||||
print("\n");
|
||||
}
|
||||
// r1 = r->s1;
|
||||
// if(r1 != nil) {
|
||||
// print(" succ:");
|
||||
// for(; r1 != R; r1 = r1->s1)
|
||||
// print(" %.4ud", (int)r1->prog->pc);
|
||||
// print("\n");
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,8 +338,6 @@ enum
|
||||
D_STATIC = (D_NONE+4),
|
||||
D_AUTO = (D_NONE+5),
|
||||
D_PARAM = (D_NONE+6),
|
||||
|
||||
D_LAST = (D_NONE+26),
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -70,7 +70,6 @@ struct Sym
|
||||
vlong value;
|
||||
ushort type;
|
||||
char *name;
|
||||
char* labelname;
|
||||
char sym;
|
||||
};
|
||||
#define S ((Sym*)0)
|
||||
@@ -149,8 +148,6 @@ void newio(void);
|
||||
void newfile(char*, int);
|
||||
Sym* slookup(char*);
|
||||
Sym* lookup(void);
|
||||
Sym* labellookup(Sym*);
|
||||
void settext(LSym*);
|
||||
void syminit(Sym*);
|
||||
int32 yylex(void);
|
||||
int getc(void);
|
||||
|
||||
@@ -71,11 +71,15 @@ prog:
|
||||
line
|
||||
|
||||
line:
|
||||
LNAME ':'
|
||||
LLAB ':'
|
||||
{
|
||||
if($1->value != pc)
|
||||
yyerror("redeclaration of %s", $1->name);
|
||||
$1->value = pc;
|
||||
}
|
||||
line
|
||||
| LNAME ':'
|
||||
{
|
||||
$1 = labellookup($1);
|
||||
if($1->type == LLAB && $1->value != pc)
|
||||
yyerror("redeclaration of %s (%s)", $1->labelname, $1->name);
|
||||
$1->type = LLAB;
|
||||
$1->value = pc;
|
||||
}
|
||||
@@ -193,13 +197,11 @@ spec1: /* DATA */
|
||||
spec2: /* TEXT */
|
||||
mem ',' imm2
|
||||
{
|
||||
settext($1.sym);
|
||||
$$.from = $1;
|
||||
$$.to = $3;
|
||||
}
|
||||
| mem ',' con ',' imm2
|
||||
{
|
||||
settext($1.sym);
|
||||
$$.from = $1;
|
||||
$$.from.scale = $3;
|
||||
$$.to = $5;
|
||||
@@ -361,10 +363,15 @@ rel:
|
||||
}
|
||||
| LNAME offset
|
||||
{
|
||||
$1 = labellookup($1);
|
||||
$$ = nullgen;
|
||||
if(pass == 2 && $1->type != LLAB)
|
||||
yyerror("undefined label: %s", $1->labelname);
|
||||
if(pass == 2)
|
||||
yyerror("undefined label: %s", $1->name);
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $2;
|
||||
}
|
||||
| LLAB offset
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $1->value + $2;
|
||||
}
|
||||
|
||||
1156
src/cmd/6a/y.tab.c
1156
src/cmd/6a/y.tab.c
File diff suppressed because it is too large
Load Diff
@@ -81,7 +81,7 @@ datagostring(Strlit *sval, Addr *a)
|
||||
a->sym = linksym(sym);
|
||||
a->node = sym->def;
|
||||
a->offset = 0; // header
|
||||
a->etype = TSTRING;
|
||||
a->etype = TINT32;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -63,8 +63,8 @@ enum
|
||||
|
||||
uint32 BLOAD(Reg*);
|
||||
uint32 BSTORE(Reg*);
|
||||
uint64 LOAD(Reg*);
|
||||
uint64 STORE(Reg*);
|
||||
uint32 LOAD(Reg*);
|
||||
uint32 STORE(Reg*);
|
||||
*/
|
||||
|
||||
// A Reg is a wrapper around a single Prog (one instruction) that holds
|
||||
@@ -75,18 +75,12 @@ struct Reg
|
||||
{
|
||||
Flow f;
|
||||
|
||||
Bits set; // regopt variables written by this instruction.
|
||||
Bits use1; // regopt variables read by prog->from.
|
||||
Bits use2; // regopt variables read by prog->to.
|
||||
Bits set; // variables written by this instruction.
|
||||
Bits use1; // variables read by prog->from.
|
||||
Bits use2; // variables read by prog->to.
|
||||
|
||||
// refahead/refbehind are the regopt variables whose current
|
||||
// value may be used in the following/preceding instructions
|
||||
// up to a CALL (or the value is clobbered).
|
||||
Bits refbehind;
|
||||
Bits refahead;
|
||||
// calahead/calbehind are similar, but for variables in
|
||||
// instructions that are reachable after hitting at least one
|
||||
// CALL.
|
||||
Bits calbehind;
|
||||
Bits calahead;
|
||||
Bits regdiff;
|
||||
@@ -99,16 +93,6 @@ struct Reg
|
||||
|
||||
#define NRGN 600
|
||||
/*c2go enum { NRGN = 600 }; */
|
||||
|
||||
// A Rgn represents a single regopt variable over a region of code
|
||||
// where a register could potentially be dedicated to that variable.
|
||||
// The code encompassed by a Rgn is defined by the flow graph,
|
||||
// starting at enter, flood-filling forward while varno is refahead
|
||||
// and backward while varno is refbehind, and following branches. A
|
||||
// single variable may be represented by multiple disjoint Rgns and
|
||||
// each Rgn may choose a different register for that variable.
|
||||
// Registers are allocated to regions greedily in order of descending
|
||||
// cost.
|
||||
struct Rgn
|
||||
{
|
||||
Reg* enter;
|
||||
@@ -156,8 +140,8 @@ void prop(Reg*, Bits, Bits);
|
||||
void synch(Reg*, Bits);
|
||||
uint32 allreg(uint32, Rgn*);
|
||||
void paint1(Reg*, int);
|
||||
uint32 paint2(Reg*, int, int);
|
||||
void paint3(Reg*, int, uint32, int);
|
||||
uint32 paint2(Reg*, int);
|
||||
void paint3(Reg*, int, int32, int);
|
||||
void addreg(Adr*, int);
|
||||
void dumpone(Flow*, int);
|
||||
void dumpit(char*, Flow*, int);
|
||||
@@ -169,10 +153,10 @@ void peep(Prog*);
|
||||
void excise(Flow*);
|
||||
int copyu(Prog*, Adr*, Adr*);
|
||||
|
||||
uint32 RtoB(int);
|
||||
uint32 FtoB(int);
|
||||
int BtoR(uint32);
|
||||
int BtoF(uint32);
|
||||
int32 RtoB(int);
|
||||
int32 FtoB(int);
|
||||
int BtoR(int32);
|
||||
int BtoF(int32);
|
||||
|
||||
/*
|
||||
* prog.c
|
||||
@@ -181,8 +165,8 @@ typedef struct ProgInfo ProgInfo;
|
||||
struct ProgInfo
|
||||
{
|
||||
uint32 flags; // the bits below
|
||||
uint32 reguse; // registers implicitly used by this instruction
|
||||
uint32 regset; // registers implicitly set by this instruction
|
||||
uint32 reguse; // required registers used by this instruction
|
||||
uint32 regset; // required registers set by this instruction
|
||||
uint32 regindex; // registers used by addressing mode
|
||||
};
|
||||
|
||||
@@ -203,12 +187,12 @@ enum
|
||||
SizeF = 1<<7, // float aka float32
|
||||
SizeD = 1<<8, // double aka float64
|
||||
|
||||
// Left side (Prog.from): address taken, read, write.
|
||||
// Left side: address taken, read, write.
|
||||
LeftAddr = 1<<9,
|
||||
LeftRead = 1<<10,
|
||||
LeftWrite = 1<<11,
|
||||
|
||||
// Right side (Prog.to): address taken, read, write.
|
||||
// Right side: address taken, read, write.
|
||||
RightAddr = 1<<12,
|
||||
RightRead = 1<<13,
|
||||
RightWrite = 1<<14,
|
||||
|
||||
140
src/cmd/6g/reg.c
140
src/cmd/6g/reg.c
@@ -34,7 +34,7 @@
|
||||
#include "opt.h"
|
||||
|
||||
#define NREGVAR 32 /* 16 general + 16 floating */
|
||||
#define REGBITS ((uint64)0xffffffffull)
|
||||
#define REGBITS ((uint32)0xffffffff)
|
||||
/*c2go enum {
|
||||
NREGVAR = 32,
|
||||
REGBITS = 0xffffffff,
|
||||
@@ -71,7 +71,7 @@ setaddrs(Bits bit)
|
||||
i = bnum(bit);
|
||||
node = var[i].node;
|
||||
n = var[i].name;
|
||||
biclr(&bit, i);
|
||||
bit.b[i/32] &= ~(1L<<(i%32));
|
||||
|
||||
// disable all pieces of that variable
|
||||
for(i=0; i<nvar; i++) {
|
||||
@@ -364,7 +364,7 @@ loop2:
|
||||
rgp->varno = i;
|
||||
change = 0;
|
||||
paint1(r, i);
|
||||
biclr(&bit, i);
|
||||
bit.b[i/32] &= ~(1L<<(i%32));
|
||||
if(change <= 0)
|
||||
continue;
|
||||
rgp->cost = change;
|
||||
@@ -389,13 +389,9 @@ brk:
|
||||
* replace code (paint3)
|
||||
*/
|
||||
rgp = region;
|
||||
if(debug['R'] && debug['v'])
|
||||
print("\nregisterizing\n");
|
||||
for(i=0; i<nregion; i++) {
|
||||
if(debug['R'] && debug['v'])
|
||||
print("region %d: cost %d varno %d enter %d\n", i, rgp->cost, rgp->varno, rgp->enter->f.prog->pc);
|
||||
bit = blsh(rgp->varno);
|
||||
vreg = paint2(rgp->enter, rgp->varno, 0);
|
||||
vreg = paint2(rgp->enter, rgp->varno);
|
||||
vreg = allreg(vreg, rgp);
|
||||
if(rgp->regno != 0) {
|
||||
if(debug['R'] && debug['v']) {
|
||||
@@ -410,6 +406,9 @@ brk:
|
||||
rgp++;
|
||||
}
|
||||
|
||||
if(debug['R'] && debug['v'])
|
||||
dumpit("pass6", &firstr->f, 1);
|
||||
|
||||
/*
|
||||
* free aux structures. peep allocates new ones.
|
||||
*/
|
||||
@@ -418,15 +417,6 @@ brk:
|
||||
flowend(g);
|
||||
firstr = R;
|
||||
|
||||
if(debug['R'] && debug['v']) {
|
||||
// Rebuild flow graph, since we inserted instructions
|
||||
g = flowstart(firstp, sizeof(Reg));
|
||||
firstr = (Reg*)g->start;
|
||||
dumpit("pass6", &firstr->f, 1);
|
||||
flowend(g);
|
||||
firstr = R;
|
||||
}
|
||||
|
||||
/*
|
||||
* pass 7
|
||||
* peep-hole on basic block
|
||||
@@ -487,7 +477,7 @@ walkvardef(Node *n, Reg *r, int active)
|
||||
break;
|
||||
for(v=n->opt; v!=nil; v=v->nextinnode) {
|
||||
bn = v - var;
|
||||
biset(&r1->act, bn);
|
||||
r1->act.b[bn/32] |= 1L << (bn%32);
|
||||
}
|
||||
if(r1->f.prog->as == ACALL)
|
||||
break;
|
||||
@@ -631,9 +621,6 @@ mkvar(Reg *r, Adr *a)
|
||||
if(r != R)
|
||||
r->use1.b[0] |= doregbits(a->index);
|
||||
|
||||
if(t >= D_INDIR && t < 2*D_INDIR)
|
||||
goto none;
|
||||
|
||||
switch(t) {
|
||||
default:
|
||||
regu = doregbits(t);
|
||||
@@ -835,10 +822,10 @@ prop(Reg *r, Bits ref, Bits cal)
|
||||
for(z=0; z<BITS; z++) {
|
||||
if(cal.b[z] == 0)
|
||||
continue;
|
||||
for(i=0; i<64; i++) {
|
||||
if(z*64+i >= nvar || ((cal.b[z]>>i)&1) == 0)
|
||||
for(i=0; i<32; i++) {
|
||||
if(z*32+i >= nvar || ((cal.b[z]>>i)&1) == 0)
|
||||
continue;
|
||||
v = var+z*64+i;
|
||||
v = var+z*32+i;
|
||||
if(v->node->opt == nil) // v represents fixed register, not Go variable
|
||||
continue;
|
||||
|
||||
@@ -854,10 +841,10 @@ prop(Reg *r, Bits ref, Bits cal)
|
||||
// This will set the bits at most twice, keeping the overall loop linear.
|
||||
v1 = v->node->opt;
|
||||
j = v1 - var;
|
||||
if(v == v1 || !btest(&cal, j)) {
|
||||
if(v == v1 || ((cal.b[j/32]>>(j&31))&1) == 0) {
|
||||
for(; v1 != nil; v1 = v1->nextinnode) {
|
||||
j = v1 - var;
|
||||
biset(&cal, j);
|
||||
cal.b[j/32] |= 1UL<<(j&31);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -972,10 +959,10 @@ paint1(Reg *r, int bn)
|
||||
{
|
||||
Reg *r1;
|
||||
int z;
|
||||
uint64 bb;
|
||||
uint32 bb;
|
||||
|
||||
z = bn/64;
|
||||
bb = 1LL<<(bn%64);
|
||||
z = bn/32;
|
||||
bb = 1L<<(bn%32);
|
||||
if(r->act.b[z] & bb)
|
||||
return;
|
||||
for(;;) {
|
||||
@@ -1030,14 +1017,54 @@ paint1(Reg *r, int bn)
|
||||
}
|
||||
|
||||
uint32
|
||||
paint2(Reg *r, int bn, int depth)
|
||||
regset(Reg *r, uint32 bb)
|
||||
{
|
||||
uint32 b, set;
|
||||
Adr v;
|
||||
int c;
|
||||
|
||||
set = 0;
|
||||
v = zprog.from;
|
||||
while(b = bb & ~(bb-1)) {
|
||||
v.type = b & 0xFFFF? BtoR(b): BtoF(b);
|
||||
if(v.type == 0)
|
||||
fatal("zero v.type for %#ux", b);
|
||||
c = copyu(r->f.prog, &v, nil);
|
||||
if(c == 3)
|
||||
set |= b;
|
||||
bb &= ~b;
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
uint32
|
||||
reguse(Reg *r, uint32 bb)
|
||||
{
|
||||
uint32 b, set;
|
||||
Adr v;
|
||||
int c;
|
||||
|
||||
set = 0;
|
||||
v = zprog.from;
|
||||
while(b = bb & ~(bb-1)) {
|
||||
v.type = b & 0xFFFF? BtoR(b): BtoF(b);
|
||||
c = copyu(r->f.prog, &v, nil);
|
||||
if(c == 1 || c == 2 || c == 4)
|
||||
set |= b;
|
||||
bb &= ~b;
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
uint32
|
||||
paint2(Reg *r, int bn)
|
||||
{
|
||||
Reg *r1;
|
||||
int z;
|
||||
uint64 bb, vreg;
|
||||
uint32 bb, vreg, x;
|
||||
|
||||
z = bn/64;
|
||||
bb = 1LL << (bn%64);
|
||||
z = bn/32;
|
||||
bb = 1L << (bn%32);
|
||||
vreg = regbits;
|
||||
if(!(r->act.b[z] & bb))
|
||||
return vreg;
|
||||
@@ -1054,9 +1081,6 @@ paint2(Reg *r, int bn, int depth)
|
||||
r = r1;
|
||||
}
|
||||
for(;;) {
|
||||
if(debug['R'] && debug['v'])
|
||||
print(" paint2 %d %P\n", depth, r->f.prog);
|
||||
|
||||
r->act.b[z] &= ~bb;
|
||||
|
||||
vreg |= r->regu;
|
||||
@@ -1064,14 +1088,14 @@ paint2(Reg *r, int bn, int depth)
|
||||
if(r->refbehind.b[z] & bb)
|
||||
for(r1 = (Reg*)r->f.p2; r1 != R; r1 = (Reg*)r1->f.p2link)
|
||||
if(r1->refahead.b[z] & bb)
|
||||
vreg |= paint2(r1, bn, depth+1);
|
||||
vreg |= paint2(r1, bn);
|
||||
|
||||
if(!(r->refahead.b[z] & bb))
|
||||
break;
|
||||
r1 = (Reg*)r->f.s2;
|
||||
if(r1 != R)
|
||||
if(r1->refbehind.b[z] & bb)
|
||||
vreg |= paint2(r1, bn, depth+1);
|
||||
vreg |= paint2(r1, bn);
|
||||
r = (Reg*)r->f.s1;
|
||||
if(r == R)
|
||||
break;
|
||||
@@ -1081,19 +1105,27 @@ paint2(Reg *r, int bn, int depth)
|
||||
break;
|
||||
}
|
||||
|
||||
bb = vreg;
|
||||
for(; r; r=(Reg*)r->f.s1) {
|
||||
x = r->regu & ~bb;
|
||||
if(x) {
|
||||
vreg |= reguse(r, x);
|
||||
bb |= regset(r, x);
|
||||
}
|
||||
}
|
||||
return vreg;
|
||||
}
|
||||
|
||||
void
|
||||
paint3(Reg *r, int bn, uint32 rb, int rn)
|
||||
paint3(Reg *r, int bn, int32 rb, int rn)
|
||||
{
|
||||
Reg *r1;
|
||||
Prog *p;
|
||||
int z;
|
||||
uint64 bb;
|
||||
uint32 bb;
|
||||
|
||||
z = bn/64;
|
||||
bb = 1LL << (bn%64);
|
||||
z = bn/32;
|
||||
bb = 1L << (bn%32);
|
||||
if(r->act.b[z] & bb)
|
||||
return;
|
||||
for(;;) {
|
||||
@@ -1166,7 +1198,7 @@ addreg(Adr *a, int rn)
|
||||
ostats.ncvtreg++;
|
||||
}
|
||||
|
||||
uint32
|
||||
int32
|
||||
RtoB(int r)
|
||||
{
|
||||
|
||||
@@ -1176,7 +1208,7 @@ RtoB(int r)
|
||||
}
|
||||
|
||||
int
|
||||
BtoR(uint32 b)
|
||||
BtoR(int32 b)
|
||||
{
|
||||
b &= 0xffffL;
|
||||
if(nacl)
|
||||
@@ -1192,7 +1224,7 @@ BtoR(uint32 b)
|
||||
* ...
|
||||
* 31 X15
|
||||
*/
|
||||
uint32
|
||||
int32
|
||||
FtoB(int f)
|
||||
{
|
||||
if(f < D_X0 || f > D_X15)
|
||||
@@ -1201,7 +1233,7 @@ FtoB(int f)
|
||||
}
|
||||
|
||||
int
|
||||
BtoF(uint32 b)
|
||||
BtoF(int32 b)
|
||||
{
|
||||
|
||||
b &= 0xFFFF0000L;
|
||||
@@ -1272,14 +1304,12 @@ dumpit(char *str, Flow *r0, int isreg)
|
||||
print(" %.4ud", (int)r1->prog->pc);
|
||||
print("\n");
|
||||
}
|
||||
// Print successors if it's not just the next one
|
||||
if(r->s1 != r->link || r->s2 != nil) {
|
||||
print(" succ:");
|
||||
if(r->s1 != nil)
|
||||
print(" %.4ud", (int)r->s1->prog->pc);
|
||||
if(r->s2 != nil)
|
||||
print(" %.4ud", (int)r->s2->prog->pc);
|
||||
print("\n");
|
||||
}
|
||||
// r1 = r->s1;
|
||||
// if(r1 != R) {
|
||||
// print(" succ:");
|
||||
// for(; r1 != R; r1 = r1->s1)
|
||||
// print(" %.4ud", (int)r1->prog->pc);
|
||||
// print("\n");
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -865,8 +865,6 @@ enum
|
||||
|
||||
D_INDIR, /* additive */
|
||||
|
||||
D_LAST,
|
||||
|
||||
T_TYPE = 1<<0,
|
||||
T_INDEX = 1<<1,
|
||||
T_OFFSET = 1<<2,
|
||||
|
||||
@@ -70,7 +70,6 @@ struct Sym
|
||||
int32 value;
|
||||
ushort type;
|
||||
char *name;
|
||||
char* labelname;
|
||||
char sym;
|
||||
};
|
||||
#define S ((Sym*)0)
|
||||
@@ -149,8 +148,6 @@ void newio(void);
|
||||
void newfile(char*, int);
|
||||
Sym* slookup(char*);
|
||||
Sym* lookup(void);
|
||||
Sym* labellookup(Sym*);
|
||||
void settext(LSym*);
|
||||
void syminit(Sym*);
|
||||
int32 yylex(void);
|
||||
int getc(void);
|
||||
|
||||
@@ -74,11 +74,15 @@ prog:
|
||||
line
|
||||
|
||||
line:
|
||||
LNAME ':'
|
||||
LLAB ':'
|
||||
{
|
||||
if($1->value != pc)
|
||||
yyerror("redeclaration of %s", $1->name);
|
||||
$1->value = pc;
|
||||
}
|
||||
line
|
||||
| LNAME ':'
|
||||
{
|
||||
$1 = labellookup($1);
|
||||
if($1->type == LLAB && $1->value != pc)
|
||||
yyerror("redeclaration of %s", $1->labelname);
|
||||
$1->type = LLAB;
|
||||
$1->value = pc;
|
||||
}
|
||||
@@ -195,13 +199,11 @@ spec1: /* DATA */
|
||||
spec2: /* TEXT */
|
||||
mem ',' imm2
|
||||
{
|
||||
settext($1.sym);
|
||||
$$.from = $1;
|
||||
$$.to = $3;
|
||||
}
|
||||
| mem ',' con ',' imm2
|
||||
{
|
||||
settext($1.sym);
|
||||
$$.from = $1;
|
||||
$$.from.scale = $3;
|
||||
$$.to = $5;
|
||||
@@ -360,10 +362,15 @@ rel:
|
||||
}
|
||||
| LNAME offset
|
||||
{
|
||||
$1 = labellookup($1);
|
||||
$$ = nullgen;
|
||||
if(pass == 2 && $1->type != LLAB)
|
||||
yyerror("undefined label: %s", $1->labelname);
|
||||
if(pass == 2)
|
||||
yyerror("undefined label: %s", $1->name);
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $2;
|
||||
}
|
||||
| LLAB offset
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $1->value + $2;
|
||||
}
|
||||
|
||||
1148
src/cmd/8a/y.tab.c
1148
src/cmd/8a/y.tab.c
File diff suppressed because it is too large
Load Diff
@@ -81,7 +81,7 @@ datagostring(Strlit *sval, Addr *a)
|
||||
a->sym = linksym(sym);
|
||||
a->node = sym->def;
|
||||
a->offset = 0; // header
|
||||
a->etype = TSTRING;
|
||||
a->etype = TINT32;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -63,8 +63,8 @@ enum
|
||||
|
||||
uint32 BLOAD(Reg*);
|
||||
uint32 BSTORE(Reg*);
|
||||
uint64 LOAD(Reg*);
|
||||
uint64 STORE(Reg*);
|
||||
uint32 LOAD(Reg*);
|
||||
uint32 STORE(Reg*);
|
||||
*/
|
||||
|
||||
// A Reg is a wrapper around a single Prog (one instruction) that holds
|
||||
@@ -75,18 +75,12 @@ struct Reg
|
||||
{
|
||||
Flow f;
|
||||
|
||||
Bits set; // regopt variables written by this instruction.
|
||||
Bits use1; // regopt variables read by prog->from.
|
||||
Bits use2; // regopt variables read by prog->to.
|
||||
Bits set; // variables written by this instruction.
|
||||
Bits use1; // variables read by prog->from.
|
||||
Bits use2; // variables read by prog->to.
|
||||
|
||||
// refahead/refbehind are the regopt variables whose current
|
||||
// value may be used in the following/preceding instructions
|
||||
// up to a CALL (or the value is clobbered).
|
||||
Bits refbehind;
|
||||
Bits refahead;
|
||||
// calahead/calbehind are similar, but for variables in
|
||||
// instructions that are reachable after hitting at least one
|
||||
// CALL.
|
||||
Bits calbehind;
|
||||
Bits calahead;
|
||||
Bits regdiff;
|
||||
@@ -112,16 +106,6 @@ struct Reg
|
||||
|
||||
#define NRGN 600
|
||||
/*c2go enum { NRGN = 600 }; */
|
||||
|
||||
// A Rgn represents a single regopt variable over a region of code
|
||||
// where a register could potentially be dedicated to that variable.
|
||||
// The code encompassed by a Rgn is defined by the flow graph,
|
||||
// starting at enter, flood-filling forward while varno is refahead
|
||||
// and backward while varno is refbehind, and following branches. A
|
||||
// single variable may be represented by multiple disjoint Rgns and
|
||||
// each Rgn may choose a different register for that variable.
|
||||
// Registers are allocated to regions greedily in order of descending
|
||||
// cost.
|
||||
struct Rgn
|
||||
{
|
||||
Reg* enter;
|
||||
@@ -174,8 +158,8 @@ void loopit(Reg*, int32);
|
||||
void synch(Reg*, Bits);
|
||||
uint32 allreg(uint32, Rgn*);
|
||||
void paint1(Reg*, int);
|
||||
uint32 paint2(Reg*, int, int);
|
||||
void paint3(Reg*, int, uint32, int);
|
||||
uint32 paint2(Reg*, int);
|
||||
void paint3(Reg*, int, int32, int);
|
||||
void addreg(Adr*, int);
|
||||
void dumpone(Flow*, int);
|
||||
void dumpit(char*, Flow*, int);
|
||||
@@ -187,10 +171,10 @@ void peep(Prog*);
|
||||
void excise(Flow*);
|
||||
int copyu(Prog*, Adr*, Adr*);
|
||||
|
||||
uint32 RtoB(int);
|
||||
uint32 FtoB(int);
|
||||
int BtoR(uint32);
|
||||
int BtoF(uint32);
|
||||
int32 RtoB(int);
|
||||
int32 FtoB(int);
|
||||
int BtoR(int32);
|
||||
int BtoF(int32);
|
||||
|
||||
/*
|
||||
* prog.c
|
||||
@@ -199,8 +183,8 @@ typedef struct ProgInfo ProgInfo;
|
||||
struct ProgInfo
|
||||
{
|
||||
uint32 flags; // the bits below
|
||||
uint32 reguse; // registers implicitly used by this instruction
|
||||
uint32 regset; // registers implicitly set by this instruction
|
||||
uint32 reguse; // required registers used by this instruction
|
||||
uint32 regset; // required registers set by this instruction
|
||||
uint32 regindex; // registers used by addressing mode
|
||||
};
|
||||
|
||||
@@ -221,12 +205,12 @@ enum
|
||||
SizeF = 1<<7, // float aka float32
|
||||
SizeD = 1<<8, // double aka float64
|
||||
|
||||
// Left side (Prog.from): address taken, read, write.
|
||||
// Left side: address taken, read, write.
|
||||
LeftAddr = 1<<9,
|
||||
LeftRead = 1<<10,
|
||||
LeftWrite = 1<<11,
|
||||
|
||||
// Right side (Prog.to): address taken, read, write.
|
||||
// Right side: address taken, read, write.
|
||||
RightAddr = 1<<12,
|
||||
RightRead = 1<<13,
|
||||
RightWrite = 1<<14,
|
||||
|
||||
135
src/cmd/8g/reg.c
135
src/cmd/8g/reg.c
@@ -34,7 +34,7 @@
|
||||
#include "opt.h"
|
||||
|
||||
#define NREGVAR 16 /* 8 integer + 8 floating */
|
||||
#define REGBITS ((uint64)0xffffull)
|
||||
#define REGBITS ((uint32)0xffff)
|
||||
/*c2go enum {
|
||||
NREGVAR = 16,
|
||||
REGBITS = (1<<NREGVAR) - 1,
|
||||
@@ -71,7 +71,7 @@ setaddrs(Bits bit)
|
||||
i = bnum(bit);
|
||||
node = var[i].node;
|
||||
n = var[i].name;
|
||||
biclr(&bit, i);
|
||||
bit.b[i/32] &= ~(1L<<(i%32));
|
||||
|
||||
// disable all pieces of that variable
|
||||
for(i=0; i<nvar; i++) {
|
||||
@@ -336,7 +336,7 @@ loop2:
|
||||
rgp->varno = i;
|
||||
change = 0;
|
||||
paint1(r, i);
|
||||
biclr(&bit, i);
|
||||
bit.b[i/32] &= ~(1L<<(i%32));
|
||||
if(change <= 0)
|
||||
continue;
|
||||
rgp->cost = change;
|
||||
@@ -358,19 +358,18 @@ brk:
|
||||
* replace code (paint3)
|
||||
*/
|
||||
rgp = region;
|
||||
if(debug['R'] && debug['v'])
|
||||
print("\nregisterizing\n");
|
||||
for(i=0; i<nregion; i++) {
|
||||
if(debug['R'] && debug['v'])
|
||||
print("region %d: cost %d varno %d enter %d\n", i, rgp->cost, rgp->varno, rgp->enter->f.prog->pc);
|
||||
bit = blsh(rgp->varno);
|
||||
vreg = paint2(rgp->enter, rgp->varno, 0);
|
||||
vreg = paint2(rgp->enter, rgp->varno);
|
||||
vreg = allreg(vreg, rgp);
|
||||
if(rgp->regno != 0)
|
||||
paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
|
||||
rgp++;
|
||||
}
|
||||
|
||||
if(debug['R'] && debug['v'])
|
||||
dumpit("pass6", &firstr->f, 1);
|
||||
|
||||
/*
|
||||
* free aux structures. peep allocates new ones.
|
||||
*/
|
||||
@@ -379,15 +378,6 @@ brk:
|
||||
flowend(g);
|
||||
firstr = R;
|
||||
|
||||
if(debug['R'] && debug['v']) {
|
||||
// Rebuild flow graph, since we inserted instructions
|
||||
g = flowstart(firstp, sizeof(Reg));
|
||||
firstr = (Reg*)g->start;
|
||||
dumpit("pass6", &firstr->f, 1);
|
||||
flowend(g);
|
||||
firstr = R;
|
||||
}
|
||||
|
||||
/*
|
||||
* pass 7
|
||||
* peep-hole on basic block
|
||||
@@ -456,7 +446,7 @@ walkvardef(Node *n, Reg *r, int active)
|
||||
break;
|
||||
for(v=n->opt; v!=nil; v=v->nextinnode) {
|
||||
bn = v - var;
|
||||
biset(&r1->act, bn);
|
||||
r1->act.b[bn/32] |= 1L << (bn%32);
|
||||
}
|
||||
if(r1->f.prog->as == ACALL)
|
||||
break;
|
||||
@@ -798,10 +788,10 @@ prop(Reg *r, Bits ref, Bits cal)
|
||||
for(z=0; z<BITS; z++) {
|
||||
if(cal.b[z] == 0)
|
||||
continue;
|
||||
for(i=0; i<64; i++) {
|
||||
if(z*64+i >= nvar || ((cal.b[z]>>i)&1) == 0)
|
||||
for(i=0; i<32; i++) {
|
||||
if(z*32+i >= nvar || ((cal.b[z]>>i)&1) == 0)
|
||||
continue;
|
||||
v = var+z*64+i;
|
||||
v = var+z*32+i;
|
||||
if(v->node->opt == nil) // v represents fixed register, not Go variable
|
||||
continue;
|
||||
|
||||
@@ -817,10 +807,10 @@ prop(Reg *r, Bits ref, Bits cal)
|
||||
// This will set the bits at most twice, keeping the overall loop linear.
|
||||
v1 = v->node->opt;
|
||||
j = v1 - var;
|
||||
if(v == v1 || !btest(&cal, j)) {
|
||||
if(v == v1 || ((cal.b[j/32]>>(j&31))&1) == 0) {
|
||||
for(; v1 != nil; v1 = v1->nextinnode) {
|
||||
j = v1 - var;
|
||||
biset(&cal, j);
|
||||
cal.b[j/32] |= 1<<(j&31);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -936,10 +926,10 @@ paint1(Reg *r, int bn)
|
||||
Reg *r1;
|
||||
Prog *p;
|
||||
int z;
|
||||
uint64 bb;
|
||||
uint32 bb;
|
||||
|
||||
z = bn/64;
|
||||
bb = 1LL<<(bn%64);
|
||||
z = bn/32;
|
||||
bb = 1L<<(bn%32);
|
||||
if(r->act.b[z] & bb)
|
||||
return;
|
||||
for(;;) {
|
||||
@@ -1006,14 +996,52 @@ paint1(Reg *r, int bn)
|
||||
}
|
||||
|
||||
uint32
|
||||
paint2(Reg *r, int bn, int depth)
|
||||
regset(Reg *r, uint32 bb)
|
||||
{
|
||||
uint32 b, set;
|
||||
Adr v;
|
||||
int c;
|
||||
|
||||
set = 0;
|
||||
v = zprog.from;
|
||||
while(b = bb & ~(bb-1)) {
|
||||
v.type = b & 0xFF ? BtoR(b): BtoF(b);
|
||||
c = copyu(r->f.prog, &v, nil);
|
||||
if(c == 3)
|
||||
set |= b;
|
||||
bb &= ~b;
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
uint32
|
||||
reguse(Reg *r, uint32 bb)
|
||||
{
|
||||
uint32 b, set;
|
||||
Adr v;
|
||||
int c;
|
||||
|
||||
set = 0;
|
||||
v = zprog.from;
|
||||
while(b = bb & ~(bb-1)) {
|
||||
v.type = b & 0xFF ? BtoR(b): BtoF(b);
|
||||
c = copyu(r->f.prog, &v, nil);
|
||||
if(c == 1 || c == 2 || c == 4)
|
||||
set |= b;
|
||||
bb &= ~b;
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
uint32
|
||||
paint2(Reg *r, int bn)
|
||||
{
|
||||
Reg *r1;
|
||||
int z;
|
||||
uint64 bb, vreg;
|
||||
uint32 bb, vreg, x;
|
||||
|
||||
z = bn/64;
|
||||
bb = 1LL << (bn%64);
|
||||
z = bn/32;
|
||||
bb = 1L << (bn%32);
|
||||
vreg = regbits;
|
||||
if(!(r->act.b[z] & bb))
|
||||
return vreg;
|
||||
@@ -1030,9 +1058,6 @@ paint2(Reg *r, int bn, int depth)
|
||||
r = r1;
|
||||
}
|
||||
for(;;) {
|
||||
if(debug['R'] && debug['v'])
|
||||
print(" paint2 %d %P\n", depth, r->f.prog);
|
||||
|
||||
r->act.b[z] &= ~bb;
|
||||
|
||||
vreg |= r->regu;
|
||||
@@ -1040,14 +1065,14 @@ paint2(Reg *r, int bn, int depth)
|
||||
if(r->refbehind.b[z] & bb)
|
||||
for(r1 = (Reg*)r->f.p2; r1 != R; r1 = (Reg*)r1->f.p2link)
|
||||
if(r1->refahead.b[z] & bb)
|
||||
vreg |= paint2(r1, bn, depth+1);
|
||||
vreg |= paint2(r1, bn);
|
||||
|
||||
if(!(r->refahead.b[z] & bb))
|
||||
break;
|
||||
r1 = (Reg*)r->f.s2;
|
||||
if(r1 != R)
|
||||
if(r1->refbehind.b[z] & bb)
|
||||
vreg |= paint2(r1, bn, depth+1);
|
||||
vreg |= paint2(r1, bn);
|
||||
r = (Reg*)r->f.s1;
|
||||
if(r == R)
|
||||
break;
|
||||
@@ -1057,19 +1082,27 @@ paint2(Reg *r, int bn, int depth)
|
||||
break;
|
||||
}
|
||||
|
||||
bb = vreg;
|
||||
for(; r; r=(Reg*)r->f.s1) {
|
||||
x = r->regu & ~bb;
|
||||
if(x) {
|
||||
vreg |= reguse(r, x);
|
||||
bb |= regset(r, x);
|
||||
}
|
||||
}
|
||||
return vreg;
|
||||
}
|
||||
|
||||
void
|
||||
paint3(Reg *r, int bn, uint32 rb, int rn)
|
||||
paint3(Reg *r, int bn, int32 rb, int rn)
|
||||
{
|
||||
Reg *r1;
|
||||
Prog *p;
|
||||
int z;
|
||||
uint64 bb;
|
||||
uint32 bb;
|
||||
|
||||
z = bn/64;
|
||||
bb = 1LL << (bn%64);
|
||||
z = bn/32;
|
||||
bb = 1L << (bn%32);
|
||||
if(r->act.b[z] & bb)
|
||||
return;
|
||||
for(;;) {
|
||||
@@ -1142,7 +1175,7 @@ addreg(Adr *a, int rn)
|
||||
ostats.ncvtreg++;
|
||||
}
|
||||
|
||||
uint32
|
||||
int32
|
||||
RtoB(int r)
|
||||
{
|
||||
|
||||
@@ -1152,7 +1185,7 @@ RtoB(int r)
|
||||
}
|
||||
|
||||
int
|
||||
BtoR(uint32 b)
|
||||
BtoR(int32 b)
|
||||
{
|
||||
|
||||
b &= 0xffL;
|
||||
@@ -1161,7 +1194,7 @@ BtoR(uint32 b)
|
||||
return bitno(b) + D_AX;
|
||||
}
|
||||
|
||||
uint32
|
||||
int32
|
||||
FtoB(int f)
|
||||
{
|
||||
if(f < D_X0 || f > D_X7)
|
||||
@@ -1170,7 +1203,7 @@ FtoB(int f)
|
||||
}
|
||||
|
||||
int
|
||||
BtoF(uint32 b)
|
||||
BtoF(int32 b)
|
||||
{
|
||||
b &= 0xFF00L;
|
||||
if(b == 0)
|
||||
@@ -1240,14 +1273,12 @@ dumpit(char *str, Flow *r0, int isreg)
|
||||
print(" %.4ud", (int)r1->prog->pc);
|
||||
print("\n");
|
||||
}
|
||||
// Print successors if it's not just the next one
|
||||
if(r->s1 != r->link || r->s2 != nil) {
|
||||
print(" succ:");
|
||||
if(r->s1 != nil)
|
||||
print(" %.4ud", (int)r->s1->prog->pc);
|
||||
if(r->s2 != nil)
|
||||
print(" %.4ud", (int)r->s2->prog->pc);
|
||||
print("\n");
|
||||
}
|
||||
// r1 = r->s1;
|
||||
// if(r1 != nil) {
|
||||
// print(" succ:");
|
||||
// for(; r1 != R; r1 = r1->s1)
|
||||
// print(" %.4ud", (int)r1->prog->pc);
|
||||
// print("\n");
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -654,8 +654,6 @@ enum
|
||||
|
||||
D_CONST2 = D_INDIR+D_INDIR,
|
||||
|
||||
D_LAST,
|
||||
|
||||
T_TYPE = 1<<0,
|
||||
T_INDEX = 1<<1,
|
||||
T_OFFSET = 1<<2,
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# Copyright 2012 The Go Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
include ../../Make.dist
|
||||
|
||||
install: y.tab.h
|
||||
|
||||
y.tab.h: a.y
|
||||
LANG=C LANGUAGE=en_US.UTF8 bison -d -v -y a.y
|
||||
170
src/cmd/9a/a.h
170
src/cmd/9a/a.h
@@ -1,170 +0,0 @@
|
||||
// cmd/9a/a.h from Vita Nuova.
|
||||
//
|
||||
// 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-2008 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-2008 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 "../9l/9.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
|
||||
#define NINCLUDE 10
|
||||
#define NHUNK 10000
|
||||
#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;
|
||||
vlong value;
|
||||
ushort type;
|
||||
char *name;
|
||||
char* labelname;
|
||||
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,
|
||||
};
|
||||
|
||||
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 nosched;
|
||||
EXTERN int ninclude;
|
||||
EXTERN int32 nsymb;
|
||||
EXTERN Addr nullgen;
|
||||
EXTERN char* outfile;
|
||||
EXTERN int pass;
|
||||
EXTERN int32 pc;
|
||||
EXTERN int peekc;
|
||||
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);
|
||||
Sym* labellookup(Sym*);
|
||||
void settext(LSym*);
|
||||
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);
|
||||
void outcode(int, Addr*, int, Addr*);
|
||||
void outgcode(int, Addr*, int, Addr*, Addr*);
|
||||
int filbuf(void);
|
||||
Sym* getsym(void);
|
||||
void domacro(void);
|
||||
void macund(void);
|
||||
void macdef(void);
|
||||
void macexpand(Sym*, char*);
|
||||
void macinc(void);
|
||||
void macprag(void);
|
||||
void maclin(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*);
|
||||
991
src/cmd/9a/a.y
991
src/cmd/9a/a.y
@@ -1,991 +0,0 @@
|
||||
// cmd/9a/a.y from Vita Nuova.
|
||||
//
|
||||
// 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-2008 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-2008 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 <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 *sym;
|
||||
vlong lval;
|
||||
double dval;
|
||||
char sval[8];
|
||||
Addr addr;
|
||||
}
|
||||
%left '|'
|
||||
%left '^'
|
||||
%left '&'
|
||||
%left '<' '>'
|
||||
%left '+' '-'
|
||||
%left '*' '/' '%'
|
||||
%token <lval> LMOVW LMOVB LABS LLOGW LSHW LADDW LCMP LCROP
|
||||
%token <lval> LBRA LFMOV LFCONV LFCMP LFADD LFMA LTRAP LXORW
|
||||
%token <lval> LNOP LEND LRETT LWORD LTEXT LDATA LRETRN
|
||||
%token <lval> LCONST LSP LSB LFP LPC LCREG LFLUSH
|
||||
%token <lval> LREG LFREG LR LCR LF LFPSCR
|
||||
%token <lval> LLR LCTR LSPR LSPREG LSEG LMSR
|
||||
%token <lval> LPCDAT LFUNCDAT LSCHED LXLD LXST LXOP LXMV
|
||||
%token <lval> LRLWM LMOVMW LMOVEM LMOVFL LMTFSB LMA
|
||||
%token <dval> LFCONST
|
||||
%token <sval> LSCONST
|
||||
%token <sym> LNAME LLAB LVAR
|
||||
%type <lval> con expr pointer offset sreg
|
||||
%type <addr> addr rreg regaddr name creg freg xlreg lr ctr
|
||||
%type <addr> imm ximm fimm rel psr lcr cbit fpscr fpscrf msr mask
|
||||
%%
|
||||
prog:
|
||||
| prog line
|
||||
|
||||
line:
|
||||
LNAME ':'
|
||||
{
|
||||
$1 = labellookup($1);
|
||||
if($1->type == LLAB && $1->value != pc)
|
||||
yyerror("redeclaration of %s", $1->labelname);
|
||||
$1->type = LLAB;
|
||||
$1->value = pc;
|
||||
}
|
||||
line
|
||||
| LNAME '=' expr ';'
|
||||
{
|
||||
$1->type = LVAR;
|
||||
$1->value = $3;
|
||||
}
|
||||
| LVAR '=' expr ';'
|
||||
{
|
||||
if($1->value != $3)
|
||||
yyerror("redeclaration of %s", $1->name);
|
||||
$1->value = $3;
|
||||
}
|
||||
| LSCHED ';'
|
||||
{
|
||||
nosched = $1;
|
||||
}
|
||||
| ';'
|
||||
| inst ';'
|
||||
| error ';'
|
||||
|
||||
inst:
|
||||
/*
|
||||
* load ints and bytes
|
||||
*/
|
||||
LMOVW rreg ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVW addr ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVW regaddr ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVB rreg ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVB addr ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVB regaddr ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
/*
|
||||
* load floats
|
||||
*/
|
||||
| LFMOV addr ',' freg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LFMOV regaddr ',' freg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LFMOV fimm ',' freg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LFMOV freg ',' freg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LFMOV freg ',' addr
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LFMOV freg ',' regaddr
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
/*
|
||||
* store ints and bytes
|
||||
*/
|
||||
| LMOVW rreg ',' addr
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVW rreg ',' regaddr
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVB rreg ',' addr
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVB rreg ',' regaddr
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
/*
|
||||
* store floats
|
||||
*/
|
||||
| LMOVW freg ',' addr
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVW freg ',' regaddr
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
/*
|
||||
* floating point status
|
||||
*/
|
||||
| LMOVW fpscr ',' freg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVW freg ',' fpscr
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVW freg ',' imm ',' fpscr
|
||||
{
|
||||
outgcode($1, &$2, NREG, &$4, &$6);
|
||||
}
|
||||
| LMOVW fpscr ',' creg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVW imm ',' fpscrf
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMTFSB imm ',' con
|
||||
{
|
||||
outcode($1, &$2, $4, &nullgen);
|
||||
}
|
||||
/*
|
||||
* field moves (mtcrf)
|
||||
*/
|
||||
| LMOVW rreg ',' imm ',' lcr
|
||||
{
|
||||
outgcode($1, &$2, NREG, &$4, &$6);
|
||||
}
|
||||
| LMOVW rreg ',' creg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVW rreg ',' lcr
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
/*
|
||||
* integer operations
|
||||
* logical instructions
|
||||
* shift instructions
|
||||
* unary instructions
|
||||
*/
|
||||
| LADDW rreg ',' sreg ',' rreg
|
||||
{
|
||||
outcode($1, &$2, $4, &$6);
|
||||
}
|
||||
| LADDW imm ',' sreg ',' rreg
|
||||
{
|
||||
outcode($1, &$2, $4, &$6);
|
||||
}
|
||||
| LADDW rreg ',' imm ',' rreg
|
||||
{
|
||||
outgcode($1, &$2, NREG, &$4, &$6);
|
||||
}
|
||||
| LADDW rreg ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LADDW imm ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LLOGW rreg ',' sreg ',' rreg
|
||||
{
|
||||
outcode($1, &$2, $4, &$6);
|
||||
}
|
||||
| LLOGW rreg ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LSHW rreg ',' sreg ',' rreg
|
||||
{
|
||||
outcode($1, &$2, $4, &$6);
|
||||
}
|
||||
| LSHW rreg ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LSHW imm ',' sreg ',' rreg
|
||||
{
|
||||
outcode($1, &$2, $4, &$6);
|
||||
}
|
||||
| LSHW imm ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LABS rreg ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LABS rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$2);
|
||||
}
|
||||
/*
|
||||
* multiply-accumulate
|
||||
*/
|
||||
| LMA rreg ',' sreg ',' rreg
|
||||
{
|
||||
outcode($1, &$2, $4, &$6);
|
||||
}
|
||||
/*
|
||||
* move immediate: macro for cau+or, addi, addis, and other combinations
|
||||
*/
|
||||
| LMOVW imm ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVW ximm ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
/*
|
||||
* condition register operations
|
||||
*/
|
||||
| LCROP cbit ',' cbit
|
||||
{
|
||||
outcode($1, &$2, $4.reg, &$4);
|
||||
}
|
||||
| LCROP cbit ',' con ',' cbit
|
||||
{
|
||||
outcode($1, &$2, $4, &$6);
|
||||
}
|
||||
/*
|
||||
* condition register moves
|
||||
* move from machine state register
|
||||
*/
|
||||
| LMOVW creg ',' creg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVW psr ',' creg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVW lcr ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVW psr ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVW xlreg ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVW rreg ',' xlreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVW creg ',' psr
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVW rreg ',' psr
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
/*
|
||||
* branch, branch conditional
|
||||
* branch conditional register
|
||||
* branch conditional to count register
|
||||
*/
|
||||
| LBRA rel
|
||||
{
|
||||
outcode($1, &nullgen, NREG, &$2);
|
||||
}
|
||||
| LBRA addr
|
||||
{
|
||||
outcode($1, &nullgen, NREG, &$2);
|
||||
}
|
||||
| LBRA '(' xlreg ')'
|
||||
{
|
||||
outcode($1, &nullgen, NREG, &$3);
|
||||
}
|
||||
| LBRA ',' rel
|
||||
{
|
||||
outcode($1, &nullgen, NREG, &$3);
|
||||
}
|
||||
| LBRA ',' addr
|
||||
{
|
||||
outcode($1, &nullgen, NREG, &$3);
|
||||
}
|
||||
| LBRA ',' '(' xlreg ')'
|
||||
{
|
||||
outcode($1, &nullgen, NREG, &$4);
|
||||
}
|
||||
| LBRA creg ',' rel
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LBRA creg ',' addr
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LBRA creg ',' '(' xlreg ')'
|
||||
{
|
||||
outcode($1, &$2, NREG, &$5);
|
||||
}
|
||||
| LBRA con ',' rel
|
||||
{
|
||||
outcode($1, &nullgen, $2, &$4);
|
||||
}
|
||||
| LBRA con ',' addr
|
||||
{
|
||||
outcode($1, &nullgen, $2, &$4);
|
||||
}
|
||||
| LBRA con ',' '(' xlreg ')'
|
||||
{
|
||||
outcode($1, &nullgen, $2, &$5);
|
||||
}
|
||||
| LBRA con ',' con ',' rel
|
||||
{
|
||||
Addr g;
|
||||
g = nullgen;
|
||||
g.type = D_CONST;
|
||||
g.offset = $2;
|
||||
outcode($1, &g, $4, &$6);
|
||||
}
|
||||
| LBRA con ',' con ',' addr
|
||||
{
|
||||
Addr g;
|
||||
g = nullgen;
|
||||
g.type = D_CONST;
|
||||
g.offset = $2;
|
||||
outcode($1, &g, $4, &$6);
|
||||
}
|
||||
| LBRA con ',' con ',' '(' xlreg ')'
|
||||
{
|
||||
Addr g;
|
||||
g = nullgen;
|
||||
g.type = D_CONST;
|
||||
g.offset = $2;
|
||||
outcode($1, &g, $4, &$7);
|
||||
}
|
||||
/*
|
||||
* conditional trap
|
||||
*/
|
||||
| LTRAP rreg ',' sreg
|
||||
{
|
||||
outcode($1, &$2, $4, &nullgen);
|
||||
}
|
||||
| LTRAP imm ',' sreg
|
||||
{
|
||||
outcode($1, &$2, $4, &nullgen);
|
||||
}
|
||||
| LTRAP rreg comma
|
||||
{
|
||||
outcode($1, &$2, NREG, &nullgen);
|
||||
}
|
||||
| LTRAP comma
|
||||
{
|
||||
outcode($1, &nullgen, NREG, &nullgen);
|
||||
}
|
||||
/*
|
||||
* floating point operate
|
||||
*/
|
||||
| LFCONV freg ',' freg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LFADD freg ',' freg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LFADD freg ',' freg ',' freg
|
||||
{
|
||||
outcode($1, &$2, $4.reg, &$6);
|
||||
}
|
||||
| LFMA freg ',' freg ',' freg ',' freg
|
||||
{
|
||||
outgcode($1, &$2, $4.reg, &$6, &$8);
|
||||
}
|
||||
| LFCMP freg ',' freg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LFCMP freg ',' freg ',' creg
|
||||
{
|
||||
outcode($1, &$2, $6.reg, &$4);
|
||||
}
|
||||
/*
|
||||
* CMP
|
||||
*/
|
||||
| LCMP rreg ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LCMP rreg ',' imm
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LCMP rreg ',' rreg ',' creg
|
||||
{
|
||||
outcode($1, &$2, $6.reg, &$4);
|
||||
}
|
||||
| LCMP rreg ',' imm ',' creg
|
||||
{
|
||||
outcode($1, &$2, $6.reg, &$4);
|
||||
}
|
||||
/*
|
||||
* rotate and mask
|
||||
*/
|
||||
| LRLWM imm ',' rreg ',' imm ',' rreg
|
||||
{
|
||||
outgcode($1, &$2, $4.reg, &$6, &$8);
|
||||
}
|
||||
| LRLWM imm ',' rreg ',' mask ',' rreg
|
||||
{
|
||||
outgcode($1, &$2, $4.reg, &$6, &$8);
|
||||
}
|
||||
| LRLWM rreg ',' rreg ',' imm ',' rreg
|
||||
{
|
||||
outgcode($1, &$2, $4.reg, &$6, &$8);
|
||||
}
|
||||
| LRLWM rreg ',' rreg ',' mask ',' rreg
|
||||
{
|
||||
outgcode($1, &$2, $4.reg, &$6, &$8);
|
||||
}
|
||||
/*
|
||||
* load/store multiple
|
||||
*/
|
||||
| LMOVMW addr ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LMOVMW rreg ',' addr
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
/*
|
||||
* various indexed load/store
|
||||
* indexed unary (eg, cache clear)
|
||||
*/
|
||||
| LXLD regaddr ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LXLD regaddr ',' imm ',' rreg
|
||||
{
|
||||
outgcode($1, &$2, NREG, &$4, &$6);
|
||||
}
|
||||
| LXST rreg ',' regaddr
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LXST rreg ',' imm ',' regaddr
|
||||
{
|
||||
outgcode($1, &$2, NREG, &$4, &$6);
|
||||
}
|
||||
| LXMV regaddr ',' rreg
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LXMV rreg ',' regaddr
|
||||
{
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LXOP regaddr
|
||||
{
|
||||
outcode($1, &$2, NREG, &nullgen);
|
||||
}
|
||||
/*
|
||||
* NOP
|
||||
*/
|
||||
| LNOP comma
|
||||
{
|
||||
outcode($1, &nullgen, NREG, &nullgen);
|
||||
}
|
||||
| LNOP rreg comma
|
||||
{
|
||||
outcode($1, &$2, NREG, &nullgen);
|
||||
}
|
||||
| LNOP freg comma
|
||||
{
|
||||
outcode($1, &$2, NREG, &nullgen);
|
||||
}
|
||||
| LNOP ',' rreg
|
||||
{
|
||||
outcode($1, &nullgen, NREG, &$3);
|
||||
}
|
||||
| LNOP ',' freg
|
||||
{
|
||||
outcode($1, &nullgen, NREG, &$3);
|
||||
}
|
||||
| LNOP imm /* SYSCALL $num: load $num to R0 before syscall and restore R0 to 0 afterwards. */
|
||||
{
|
||||
outcode($1, &$2, NREG, &nullgen);
|
||||
}
|
||||
/*
|
||||
* word
|
||||
*/
|
||||
| LWORD imm comma
|
||||
{
|
||||
outcode($1, &$2, NREG, &nullgen);
|
||||
}
|
||||
| LWORD ximm comma
|
||||
{
|
||||
outcode($1, &$2, NREG, &nullgen);
|
||||
}
|
||||
/*
|
||||
* PCDATA
|
||||
*/
|
||||
| LPCDAT imm ',' imm
|
||||
{
|
||||
if($2.type != D_CONST || $4.type != D_CONST)
|
||||
yyerror("arguments to PCDATA must be integer constants");
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
/*
|
||||
* FUNCDATA
|
||||
*/
|
||||
| LFUNCDAT imm ',' addr
|
||||
{
|
||||
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, &$2, NREG, &$4);
|
||||
}
|
||||
/*
|
||||
* END
|
||||
*/
|
||||
| LEND comma
|
||||
{
|
||||
outcode($1, &nullgen, NREG, &nullgen);
|
||||
}
|
||||
/*
|
||||
* TEXT/GLOBL
|
||||
*/
|
||||
| LTEXT name ',' imm
|
||||
{
|
||||
settext($2.sym);
|
||||
outcode($1, &$2, NREG, &$4);
|
||||
}
|
||||
| LTEXT name ',' con ',' imm
|
||||
{
|
||||
settext($2.sym);
|
||||
$6.offset &= 0xffffffffull;
|
||||
$6.offset |= (vlong)ArgsSizeUnknown << 32;
|
||||
outcode($1, &$2, $4, &$6);
|
||||
}
|
||||
| LTEXT name ',' con ',' imm '-' con
|
||||
{
|
||||
settext($2.sym);
|
||||
$6.offset &= 0xffffffffull;
|
||||
$6.offset |= ($8 & 0xffffffffull) << 32;
|
||||
outcode($1, &$2, $4, &$6);
|
||||
}
|
||||
/*
|
||||
* DATA
|
||||
*/
|
||||
| LDATA name '/' con ',' imm
|
||||
{
|
||||
outcode($1, &$2, $4, &$6);
|
||||
}
|
||||
| LDATA name '/' con ',' ximm
|
||||
{
|
||||
outcode($1, &$2, $4, &$6);
|
||||
}
|
||||
| LDATA name '/' con ',' fimm
|
||||
{
|
||||
outcode($1, &$2, $4, &$6);
|
||||
}
|
||||
/*
|
||||
* RETURN
|
||||
*/
|
||||
| LRETRN comma
|
||||
{
|
||||
outcode($1, &nullgen, NREG, &nullgen);
|
||||
}
|
||||
|
||||
rel:
|
||||
con '(' LPC ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $1 + pc;
|
||||
}
|
||||
| LNAME offset
|
||||
{
|
||||
$1 = labellookup($1);
|
||||
$$ = nullgen;
|
||||
if(pass == 2 && $1->type != LLAB)
|
||||
yyerror("undefined label: %s", $1->labelname);
|
||||
$$.type = D_BRANCH;
|
||||
$$.offset = $1->value + $2;
|
||||
}
|
||||
|
||||
rreg:
|
||||
sreg
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_REG;
|
||||
$$.reg = $1;
|
||||
}
|
||||
|
||||
xlreg:
|
||||
lr
|
||||
| ctr
|
||||
|
||||
lr:
|
||||
LLR
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_SPR;
|
||||
$$.offset = $1;
|
||||
}
|
||||
|
||||
lcr:
|
||||
LCR
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_CREG;
|
||||
$$.reg = NREG; /* whole register */
|
||||
}
|
||||
|
||||
ctr:
|
||||
LCTR
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_SPR;
|
||||
$$.offset = $1;
|
||||
}
|
||||
|
||||
msr:
|
||||
LMSR
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_MSR;
|
||||
}
|
||||
|
||||
psr:
|
||||
LSPREG
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_SPR;
|
||||
$$.offset = $1;
|
||||
}
|
||||
| LSPR '(' con ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = $1;
|
||||
$$.offset = $3;
|
||||
}
|
||||
| msr
|
||||
|
||||
fpscr:
|
||||
LFPSCR
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FPSCR;
|
||||
$$.reg = NREG;
|
||||
}
|
||||
|
||||
fpscrf:
|
||||
LFPSCR '(' con ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FPSCR;
|
||||
$$.reg = $3;
|
||||
}
|
||||
|
||||
freg:
|
||||
LFREG
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FREG;
|
||||
$$.reg = $1;
|
||||
}
|
||||
| LF '(' con ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FREG;
|
||||
$$.reg = $3;
|
||||
}
|
||||
|
||||
creg:
|
||||
LCREG
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_CREG;
|
||||
$$.reg = $1;
|
||||
}
|
||||
| LCR '(' con ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_CREG;
|
||||
$$.reg = $3;
|
||||
}
|
||||
|
||||
|
||||
cbit: con
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_REG;
|
||||
$$.reg = $1;
|
||||
}
|
||||
|
||||
mask:
|
||||
con ',' con
|
||||
{
|
||||
int mb, me;
|
||||
uint32 v;
|
||||
|
||||
$$ = nullgen;
|
||||
$$.type = D_CONST;
|
||||
mb = $1;
|
||||
me = $3;
|
||||
if(mb < 0 || mb > 31 || me < 0 || me > 31){
|
||||
yyerror("illegal mask start/end value(s)");
|
||||
mb = me = 0;
|
||||
}
|
||||
if(mb <= me)
|
||||
v = ((uint32)~0L>>mb) & (~0L<<(31-me));
|
||||
else
|
||||
v = ~(((uint32)~0L>>(me+1)) & (~0L<<(31-(mb-1))));
|
||||
$$.offset = v;
|
||||
}
|
||||
|
||||
ximm:
|
||||
'$' addr
|
||||
{
|
||||
$$ = $2;
|
||||
$$.type = D_CONST;
|
||||
}
|
||||
| '$' LSCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_SCONST;
|
||||
memcpy($$.u.sval, $2, sizeof($$.u.sval));
|
||||
}
|
||||
|
||||
fimm:
|
||||
'$' LFCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FCONST;
|
||||
$$.u.dval = $2;
|
||||
}
|
||||
| '$' '-' LFCONST
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_FCONST;
|
||||
$$.u.dval = -$3;
|
||||
}
|
||||
|
||||
imm: '$' con
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_CONST;
|
||||
$$.offset = $2;
|
||||
}
|
||||
|
||||
sreg:
|
||||
LREG
|
||||
| LR '(' con ')'
|
||||
{
|
||||
if($$ < 0 || $$ >= NREG)
|
||||
print("register value out of range\n");
|
||||
$$ = $3;
|
||||
}
|
||||
|
||||
regaddr:
|
||||
'(' sreg ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_OREG;
|
||||
$$.reg = $2;
|
||||
$$.offset = 0;
|
||||
}
|
||||
| '(' sreg '+' sreg ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_OREG;
|
||||
$$.reg = $2;
|
||||
$$.scale = $4;
|
||||
$$.offset = 0;
|
||||
}
|
||||
|
||||
addr:
|
||||
name
|
||||
| con '(' sreg ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_OREG;
|
||||
$$.reg = $3;
|
||||
$$.offset = $1;
|
||||
}
|
||||
|
||||
name:
|
||||
con '(' pointer ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_OREG;
|
||||
$$.name = $3;
|
||||
$$.sym = nil;
|
||||
$$.offset = $1;
|
||||
}
|
||||
| LNAME offset '(' pointer ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_OREG;
|
||||
$$.name = $4;
|
||||
$$.sym = linklookup(ctxt, $1->name, 0);
|
||||
$$.offset = $2;
|
||||
}
|
||||
| LNAME '<' '>' offset '(' LSB ')'
|
||||
{
|
||||
$$ = nullgen;
|
||||
$$.type = D_OREG;
|
||||
$$.name = D_STATIC;
|
||||
$$.sym = linklookup(ctxt, $1->name, 0);
|
||||
$$.offset = $4;
|
||||
}
|
||||
|
||||
comma:
|
||||
| ','
|
||||
|
||||
offset:
|
||||
{
|
||||
$$ = 0;
|
||||
}
|
||||
| '+' con
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
| '-' con
|
||||
{
|
||||
$$ = -$2;
|
||||
}
|
||||
|
||||
pointer:
|
||||
LSB
|
||||
| LSP
|
||||
| LFP
|
||||
|
||||
con:
|
||||
LCONST
|
||||
| LVAR
|
||||
{
|
||||
$$ = $1->value;
|
||||
}
|
||||
| '-' con
|
||||
{
|
||||
$$ = -$2;
|
||||
}
|
||||
| '+' con
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
| '~' con
|
||||
{
|
||||
$$ = ~$2;
|
||||
}
|
||||
| '(' expr ')'
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
|
||||
expr:
|
||||
con
|
||||
| expr '+' expr
|
||||
{
|
||||
$$ = $1 + $3;
|
||||
}
|
||||
| expr '-' expr
|
||||
{
|
||||
$$ = $1 - $3;
|
||||
}
|
||||
| expr '*' expr
|
||||
{
|
||||
$$ = $1 * $3;
|
||||
}
|
||||
| expr '/' expr
|
||||
{
|
||||
$$ = $1 / $3;
|
||||
}
|
||||
| expr '%' expr
|
||||
{
|
||||
$$ = $1 % $3;
|
||||
}
|
||||
| expr '<' '<' expr
|
||||
{
|
||||
$$ = $1 << $4;
|
||||
}
|
||||
| expr '>' '>' expr
|
||||
{
|
||||
$$ = $1 >> $4;
|
||||
}
|
||||
| expr '&' expr
|
||||
{
|
||||
$$ = $1 & $3;
|
||||
}
|
||||
| expr '^' expr
|
||||
{
|
||||
$$ = $1 ^ $3;
|
||||
}
|
||||
| expr '|' expr
|
||||
{
|
||||
$$ = $1 | $3;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. 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
|
||||
|
||||
/*
|
||||
|
||||
9a 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 Power64, referred to by these tools as
|
||||
power64 (big endian) or power64le (little endian).
|
||||
|
||||
*/
|
||||
package main
|
||||
725
src/cmd/9a/lex.c
725
src/cmd/9a/lex.c
@@ -1,725 +0,0 @@
|
||||
// cmd/9a/lex.c from Vita Nuova.
|
||||
//
|
||||
// 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-2008 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-2008 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
|
||||
pathchar(void)
|
||||
{
|
||||
return '/';
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
LinkArch* thelinkarch = &linkpower64;
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
print("usage: %ca [options] file.c...\n", thechar);
|
||||
flagprint(1);
|
||||
errorexit();
|
||||
}
|
||||
|
||||
void
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *p;
|
||||
|
||||
thechar = '9';
|
||||
thestring = "power64";
|
||||
|
||||
// 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);
|
||||
if(strcmp(p, "power64le") == 0)
|
||||
thelinkarch = &linkpower64le;
|
||||
|
||||
ctxt = linknew(thelinkarch);
|
||||
ctxt->diag = yyerror;
|
||||
ctxt->bso = &bstdout;
|
||||
ctxt->enforce_data_order = 1;
|
||||
Binit(&bstdout, 1, OWRITE);
|
||||
listinit9();
|
||||
fmtinstall('L', Lconv);
|
||||
|
||||
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, pathchar());
|
||||
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++) {
|
||||
nosched = 0;
|
||||
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,
|
||||
|
||||
"LR", LLR, D_LR,
|
||||
"CTR", LCTR, D_CTR,
|
||||
|
||||
"XER", LSPREG, D_XER,
|
||||
"MSR", LMSR, D_MSR,
|
||||
"FPSCR", LFPSCR, D_FPSCR,
|
||||
"SPR", LSPR, D_SPR,
|
||||
"DCR", LSPR, D_DCR,
|
||||
|
||||
"CR", LCR, 0,
|
||||
"CR0", LCREG, 0,
|
||||
"CR1", LCREG, 1,
|
||||
"CR2", LCREG, 2,
|
||||
"CR3", LCREG, 3,
|
||||
"CR4", LCREG, 4,
|
||||
"CR5", LCREG, 5,
|
||||
"CR6", LCREG, 6,
|
||||
"CR7", LCREG, 7,
|
||||
|
||||
"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,
|
||||
"R10", LREG, 10,
|
||||
"R11", LREG, 11,
|
||||
"R12", LREG, 12,
|
||||
"R13", LREG, 13,
|
||||
"R14", LREG, 14,
|
||||
"R15", LREG, 15,
|
||||
"R16", LREG, 16,
|
||||
"R17", LREG, 17,
|
||||
"R18", LREG, 18,
|
||||
"R19", LREG, 19,
|
||||
"R20", LREG, 20,
|
||||
"R21", LREG, 21,
|
||||
"R22", LREG, 22,
|
||||
"R23", LREG, 23,
|
||||
"R24", LREG, 24,
|
||||
"R25", LREG, 25,
|
||||
"R26", LREG, 26,
|
||||
"R27", LREG, 27,
|
||||
"R28", LREG, 28,
|
||||
"R29", LREG, 29,
|
||||
"R30", LREG, 30,
|
||||
"R31", LREG, 31,
|
||||
|
||||
"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,
|
||||
"F16", LFREG, 16,
|
||||
"F17", LFREG, 17,
|
||||
"F18", LFREG, 18,
|
||||
"F19", LFREG, 19,
|
||||
"F20", LFREG, 20,
|
||||
"F21", LFREG, 21,
|
||||
"F22", LFREG, 22,
|
||||
"F23", LFREG, 23,
|
||||
"F24", LFREG, 24,
|
||||
"F25", LFREG, 25,
|
||||
"F26", LFREG, 26,
|
||||
"F27", LFREG, 27,
|
||||
"F28", LFREG, 28,
|
||||
"F29", LFREG, 29,
|
||||
"F30", LFREG, 30,
|
||||
"F31", LFREG, 31,
|
||||
|
||||
"CREQV", LCROP, ACREQV,
|
||||
"CRXOR", LCROP, ACRXOR,
|
||||
"CRAND", LCROP, ACRAND,
|
||||
"CROR", LCROP, ACROR,
|
||||
"CRANDN", LCROP, ACRANDN,
|
||||
"CRORN", LCROP, ACRORN,
|
||||
"CRNAND", LCROP, ACRNAND,
|
||||
"CRNOR", LCROP, ACRNOR,
|
||||
|
||||
"ADD", LADDW, AADD,
|
||||
"ADDV", LADDW, AADDV,
|
||||
"ADDCC", LADDW, AADDCC,
|
||||
"ADDVCC", LADDW, AADDVCC,
|
||||
"ADDC", LADDW, AADDC,
|
||||
"ADDCV", LADDW, AADDCV,
|
||||
"ADDCCC", LADDW, AADDCCC,
|
||||
"ADDCVCC", LADDW, AADDCVCC,
|
||||
"ADDE", LLOGW, AADDE,
|
||||
"ADDEV", LLOGW, AADDEV,
|
||||
"ADDECC", LLOGW, AADDECC,
|
||||
"ADDEVCC", LLOGW, AADDEVCC,
|
||||
|
||||
"ADDME", LABS, AADDME,
|
||||
"ADDMEV", LABS, AADDMEV,
|
||||
"ADDMECC", LABS, AADDMECC,
|
||||
"ADDMEVCC", LABS, AADDMEVCC,
|
||||
"ADDZE", LABS, AADDZE,
|
||||
"ADDZEV", LABS, AADDZEV,
|
||||
"ADDZECC", LABS, AADDZECC,
|
||||
"ADDZEVCC", LABS, AADDZEVCC,
|
||||
|
||||
"SUB", LADDW, ASUB,
|
||||
"SUBV", LADDW, ASUBV,
|
||||
"SUBCC", LADDW, ASUBCC,
|
||||
"SUBVCC", LADDW, ASUBVCC,
|
||||
"SUBE", LLOGW, ASUBE,
|
||||
"SUBECC", LLOGW, ASUBECC,
|
||||
"SUBEV", LLOGW, ASUBEV,
|
||||
"SUBEVCC", LLOGW, ASUBEVCC,
|
||||
"SUBC", LADDW, ASUBC,
|
||||
"SUBCCC", LADDW, ASUBCCC,
|
||||
"SUBCV", LADDW, ASUBCV,
|
||||
"SUBCVCC", LADDW, ASUBCVCC,
|
||||
|
||||
"SUBME", LABS, ASUBME,
|
||||
"SUBMEV", LABS, ASUBMEV,
|
||||
"SUBMECC", LABS, ASUBMECC,
|
||||
"SUBMEVCC", LABS, ASUBMEVCC,
|
||||
"SUBZE", LABS, ASUBZE,
|
||||
"SUBZEV", LABS, ASUBZEV,
|
||||
"SUBZECC", LABS, ASUBZECC,
|
||||
"SUBZEVCC", LABS, ASUBZEVCC,
|
||||
|
||||
"AND", LADDW, AAND,
|
||||
"ANDCC", LADDW, AANDCC, /* includes andil & andiu */
|
||||
"ANDN", LLOGW, AANDN,
|
||||
"ANDNCC", LLOGW, AANDNCC,
|
||||
"EQV", LLOGW, AEQV,
|
||||
"EQVCC", LLOGW, AEQVCC,
|
||||
"NAND", LLOGW, ANAND,
|
||||
"NANDCC", LLOGW, ANANDCC,
|
||||
"NOR", LLOGW, ANOR,
|
||||
"NORCC", LLOGW, ANORCC,
|
||||
"OR", LADDW, AOR, /* includes oril & oriu */
|
||||
"ORCC", LADDW, AORCC,
|
||||
"ORN", LLOGW, AORN,
|
||||
"ORNCC", LLOGW, AORNCC,
|
||||
"XOR", LADDW, AXOR, /* includes xoril & xoriu */
|
||||
"XORCC", LLOGW, AXORCC,
|
||||
|
||||
"EXTSB", LABS, AEXTSB,
|
||||
"EXTSBCC", LABS, AEXTSBCC,
|
||||
"EXTSH", LABS, AEXTSH,
|
||||
"EXTSHCC", LABS, AEXTSHCC,
|
||||
|
||||
"CNTLZW", LABS, ACNTLZW,
|
||||
"CNTLZWCC", LABS, ACNTLZWCC,
|
||||
|
||||
"RLWMI", LRLWM, ARLWMI,
|
||||
"RLWMICC", LRLWM, ARLWMICC,
|
||||
"RLWNM", LRLWM, ARLWNM,
|
||||
"RLWNMCC", LRLWM, ARLWNMCC,
|
||||
|
||||
"SLW", LSHW, ASLW,
|
||||
"SLWCC", LSHW, ASLWCC,
|
||||
"SRW", LSHW, ASRW,
|
||||
"SRWCC", LSHW, ASRWCC,
|
||||
"SRAW", LSHW, ASRAW,
|
||||
"SRAWCC", LSHW, ASRAWCC,
|
||||
|
||||
"BR", LBRA, ABR,
|
||||
"BC", LBRA, ABC,
|
||||
"BCL", LBRA, ABC,
|
||||
"BL", LBRA, ABL,
|
||||
"BEQ", LBRA, ABEQ,
|
||||
"BNE", LBRA, ABNE,
|
||||
"BGT", LBRA, ABGT,
|
||||
"BGE", LBRA, ABGE,
|
||||
"BLT", LBRA, ABLT,
|
||||
"BLE", LBRA, ABLE,
|
||||
"BVC", LBRA, ABVC,
|
||||
"BVS", LBRA, ABVS,
|
||||
|
||||
"CMP", LCMP, ACMP,
|
||||
"CMPU", LCMP, ACMPU,
|
||||
"CMPW", LCMP, ACMPW,
|
||||
"CMPWU", LCMP, ACMPWU,
|
||||
|
||||
"DIVW", LLOGW, ADIVW,
|
||||
"DIVWV", LLOGW, ADIVWV,
|
||||
"DIVWCC", LLOGW, ADIVWCC,
|
||||
"DIVWVCC", LLOGW, ADIVWVCC,
|
||||
"DIVWU", LLOGW, ADIVWU,
|
||||
"DIVWUV", LLOGW, ADIVWUV,
|
||||
"DIVWUCC", LLOGW, ADIVWUCC,
|
||||
"DIVWUVCC", LLOGW, ADIVWUVCC,
|
||||
|
||||
"FABS", LFCONV, AFABS,
|
||||
"FABSCC", LFCONV, AFABSCC,
|
||||
"FNEG", LFCONV, AFNEG,
|
||||
"FNEGCC", LFCONV, AFNEGCC,
|
||||
"FNABS", LFCONV, AFNABS,
|
||||
"FNABSCC", LFCONV, AFNABSCC,
|
||||
|
||||
"FADD", LFADD, AFADD,
|
||||
"FADDCC", LFADD, AFADDCC,
|
||||
"FSUB", LFADD, AFSUB,
|
||||
"FSUBCC", LFADD, AFSUBCC,
|
||||
"FMUL", LFADD, AFMUL,
|
||||
"FMULCC", LFADD, AFMULCC,
|
||||
"FDIV", LFADD, AFDIV,
|
||||
"FDIVCC", LFADD, AFDIVCC,
|
||||
"FRSP", LFCONV, AFRSP,
|
||||
"FRSPCC", LFCONV, AFRSPCC,
|
||||
"FCTIW", LFCONV, AFCTIW,
|
||||
"FCTIWCC", LFCONV, AFCTIWCC,
|
||||
"FCTIWZ", LFCONV, AFCTIWZ,
|
||||
"FCTIWZCC", LFCONV, AFCTIWZCC,
|
||||
|
||||
"FMADD", LFMA, AFMADD,
|
||||
"FMADDCC", LFMA, AFMADDCC,
|
||||
"FMSUB", LFMA, AFMSUB,
|
||||
"FMSUBCC", LFMA, AFMSUBCC,
|
||||
"FNMADD", LFMA, AFNMADD,
|
||||
"FNMADDCC", LFMA, AFNMADDCC,
|
||||
"FNMSUB", LFMA, AFNMSUB,
|
||||
"FNMSUBCC", LFMA, AFNMSUBCC,
|
||||
"FMADDS", LFMA, AFMADDS,
|
||||
"FMADDSCC", LFMA, AFMADDSCC,
|
||||
"FMSUBS", LFMA, AFMSUBS,
|
||||
"FMSUBSCC", LFMA, AFMSUBSCC,
|
||||
"FNMADDS", LFMA, AFNMADDS,
|
||||
"FNMADDSCC", LFMA, AFNMADDSCC,
|
||||
"FNMSUBS", LFMA, AFNMSUBS,
|
||||
"FNMSUBSCC", LFMA, AFNMSUBSCC,
|
||||
|
||||
"FCMPU", LFCMP, AFCMPU,
|
||||
"FCMPO", LFCMP, AFCMPO,
|
||||
"MTFSB0", LMTFSB, AMTFSB0,
|
||||
"MTFSB1", LMTFSB, AMTFSB1,
|
||||
|
||||
"FMOVD", LFMOV, AFMOVD,
|
||||
"FMOVS", LFMOV, AFMOVS,
|
||||
"FMOVDCC", LFCONV, AFMOVDCC, /* fmr. */
|
||||
|
||||
"GLOBL", LTEXT, AGLOBL,
|
||||
|
||||
"MOVB", LMOVB, AMOVB,
|
||||
"MOVBZ", LMOVB, AMOVBZ,
|
||||
"MOVBU", LMOVB, AMOVBU,
|
||||
"MOVBZU", LMOVB, AMOVBZU,
|
||||
"MOVH", LMOVB, AMOVH,
|
||||
"MOVHZ", LMOVB, AMOVHZ,
|
||||
"MOVHU", LMOVB, AMOVHU,
|
||||
"MOVHZU", LMOVB, AMOVHZU,
|
||||
"MOVHBR", LXMV, AMOVHBR,
|
||||
"MOVWBR", LXMV, AMOVWBR,
|
||||
"MOVW", LMOVW, AMOVW,
|
||||
"MOVWU", LMOVW, AMOVWU,
|
||||
"MOVMW", LMOVMW, AMOVMW,
|
||||
"MOVFL", LMOVW, AMOVFL,
|
||||
|
||||
"MULLW", LADDW, AMULLW, /* includes multiply immediate 10-139 */
|
||||
"MULLWV", LLOGW, AMULLWV,
|
||||
"MULLWCC", LLOGW, AMULLWCC,
|
||||
"MULLWVCC", LLOGW, AMULLWVCC,
|
||||
|
||||
"MULHW", LLOGW, AMULHW,
|
||||
"MULHWCC", LLOGW, AMULHWCC,
|
||||
"MULHWU", LLOGW, AMULHWU,
|
||||
"MULHWUCC", LLOGW, AMULHWUCC,
|
||||
|
||||
"NEG", LABS, ANEG,
|
||||
"NEGV", LABS, ANEGV,
|
||||
"NEGCC", LABS, ANEGCC,
|
||||
"NEGVCC", LABS, ANEGVCC,
|
||||
|
||||
"NOP", LNOP, ANOP, /* ori 0,0,0 */
|
||||
"SYSCALL", LNOP, ASYSCALL,
|
||||
"UNDEF", LNOP, AUNDEF,
|
||||
|
||||
"RETURN", LRETRN, ARETURN,
|
||||
"RFI", LRETRN, ARFI,
|
||||
"RFCI", LRETRN, ARFCI,
|
||||
|
||||
"DATA", LDATA, ADATA,
|
||||
"END", LEND, AEND,
|
||||
"TEXT", LTEXT, ATEXT,
|
||||
|
||||
/* 64-bit instructions */
|
||||
"CNTLZD", LABS, ACNTLZD,
|
||||
"CNTLZDCC", LABS, ACNTLZDCC,
|
||||
"DIVD", LLOGW, ADIVD,
|
||||
"DIVDCC", LLOGW, ADIVDCC,
|
||||
"DIVDVCC", LLOGW, ADIVDVCC,
|
||||
"DIVDV", LLOGW, ADIVDV,
|
||||
"DIVDU", LLOGW, ADIVDU,
|
||||
"DIVDUCC", LLOGW, ADIVDUCC,
|
||||
"DIVDUVCC", LLOGW, ADIVDUVCC,
|
||||
"DIVDUV", LLOGW, ADIVDUV,
|
||||
"EXTSW", LABS, AEXTSW,
|
||||
"EXTSWCC", LABS, AEXTSWCC,
|
||||
"FCTID", LFCONV, AFCTID,
|
||||
"FCTIDCC", LFCONV, AFCTIDCC,
|
||||
"FCTIDZ", LFCONV, AFCTIDZ,
|
||||
"FCTIDZCC", LFCONV, AFCTIDZCC,
|
||||
"FCFID", LFCONV, AFCFID,
|
||||
"FCFIDCC", LFCONV, AFCFIDCC,
|
||||
"LDAR", LXLD, ALDAR,
|
||||
"MOVD", LMOVW, AMOVD,
|
||||
"MOVDU", LMOVW, AMOVDU,
|
||||
"MOVWZ", LMOVW, AMOVWZ,
|
||||
"MOVWZU", LMOVW, AMOVWZU,
|
||||
"MULHD", LLOGW, AMULHD,
|
||||
"MULHDCC", LLOGW, AMULHDCC,
|
||||
"MULHDU", LLOGW, AMULHDU,
|
||||
"MULHDUCC", LLOGW, AMULHDUCC,
|
||||
"MULLD", LADDW, AMULLD, /* includes multiply immediate? */
|
||||
"MULLDCC", LLOGW, AMULLDCC,
|
||||
"MULLDVCC", LLOGW, AMULLDVCC,
|
||||
"MULLDV", LLOGW, AMULLDV,
|
||||
"RFID", LRETRN, ARFID,
|
||||
"HRFID", LRETRN, AHRFID,
|
||||
"RLDMI", LRLWM, ARLDMI,
|
||||
"RLDMICC", LRLWM, ARLDMICC,
|
||||
"RLDC", LRLWM, ARLDC,
|
||||
"RLDCCC", LRLWM, ARLDCCC,
|
||||
"RLDCR", LRLWM, ARLDCR,
|
||||
"RLDCRCC", LRLWM, ARLDCRCC,
|
||||
"RLDCL", LRLWM, ARLDCL,
|
||||
"RLDCLCC", LRLWM, ARLDCLCC,
|
||||
"SLBIA", LNOP, ASLBIA,
|
||||
"SLBIE", LNOP, ASLBIE,
|
||||
"SLBMFEE", LABS, ASLBMFEE,
|
||||
"SLBMFEV", LABS, ASLBMFEV,
|
||||
"SLBMTE", LABS, ASLBMTE,
|
||||
"SLD", LSHW, ASLD,
|
||||
"SLDCC", LSHW, ASLDCC,
|
||||
"SRD", LSHW, ASRD,
|
||||
"SRAD", LSHW, ASRAD,
|
||||
"SRADCC", LSHW, ASRADCC,
|
||||
"SRDCC", LSHW, ASRDCC,
|
||||
"STDCCC", LXST, ASTDCCC,
|
||||
"TD", LADDW, ATD,
|
||||
|
||||
/* pseudo instructions */
|
||||
"REM", LLOGW, AREM,
|
||||
"REMCC", LLOGW, AREMCC,
|
||||
"REMV", LLOGW, AREMV,
|
||||
"REMVCC", LLOGW, AREMVCC,
|
||||
"REMU", LLOGW, AREMU,
|
||||
"REMUCC", LLOGW, AREMUCC,
|
||||
"REMUV", LLOGW, AREMUV,
|
||||
"REMUVCC", LLOGW, AREMUVCC,
|
||||
"REMD", LLOGW, AREMD,
|
||||
"REMDCC", LLOGW, AREMDCC,
|
||||
"REMDV", LLOGW, AREMDV,
|
||||
"REMDVCC", LLOGW, AREMDVCC,
|
||||
"REMDU", LLOGW, AREMDU,
|
||||
"REMDUCC", LLOGW, AREMDUCC,
|
||||
"REMDUV", LLOGW, AREMDUV,
|
||||
"REMDUVCC", LLOGW, AREMDUVCC,
|
||||
|
||||
/* special instructions */
|
||||
"DCBF", LXOP, ADCBF,
|
||||
"DCBI", LXOP, ADCBI,
|
||||
"DCBST", LXOP, ADCBST,
|
||||
"DCBT", LXOP, ADCBT,
|
||||
"DCBTST", LXOP, ADCBTST,
|
||||
"DCBZ", LXOP, ADCBZ,
|
||||
"ICBI", LXOP, AICBI,
|
||||
|
||||
"ECIWX", LXLD, AECIWX,
|
||||
"ECOWX", LXST, AECOWX,
|
||||
"LWAR", LXLD, ALWAR,
|
||||
"LWAR", LXLD, ALWAR,
|
||||
"STWCCC", LXST, ASTWCCC,
|
||||
"EIEIO", LRETRN, AEIEIO,
|
||||
"TLBIE", LNOP, ATLBIE,
|
||||
"TLBIEL", LNOP, ATLBIEL,
|
||||
"LSW", LXLD, ALSW,
|
||||
"STSW", LXST, ASTSW,
|
||||
|
||||
"ISYNC", LRETRN, AISYNC,
|
||||
"SYNC", LRETRN, ASYNC,
|
||||
"TLBSYNC", LRETRN, ATLBSYNC,
|
||||
"PTESYNC", LRETRN, APTESYNC,
|
||||
/* "TW", LADDW, ATW,*/
|
||||
|
||||
"WORD", LWORD, AWORD,
|
||||
"DWORD", LWORD, ADWORD,
|
||||
"SCHED", LSCHED, 0,
|
||||
"NOSCHED", LSCHED, 0x80,
|
||||
|
||||
"PCDATA", LPCDAT, APCDATA,
|
||||
"FUNCDATA", LFUNCDAT, AFUNCDATA,
|
||||
|
||||
0
|
||||
};
|
||||
|
||||
void
|
||||
cinit(void)
|
||||
{
|
||||
Sym *s;
|
||||
int i;
|
||||
|
||||
nullgen.type = D_NONE;
|
||||
nullgen.name = D_NONE;
|
||||
nullgen.reg = NREG;
|
||||
nullgen.scale = NREG; // replaced Gen.xreg with Prog.scale
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
cclean(void)
|
||||
{
|
||||
|
||||
outcode(AEND, &nullgen, NREG, &nullgen);
|
||||
}
|
||||
|
||||
static Prog *lastpc;
|
||||
|
||||
void
|
||||
outcode(int a, Addr *g1, int reg, Addr *g2)
|
||||
{
|
||||
Prog *p;
|
||||
Plist *pl;
|
||||
|
||||
if(pass == 1)
|
||||
goto out;
|
||||
|
||||
if(g1->scale != NREG) {
|
||||
if(reg != NREG || g2->scale != NREG)
|
||||
yyerror("bad addressing modes");
|
||||
reg = g1->scale;
|
||||
} else
|
||||
if(g2->scale != NREG) {
|
||||
if(reg != NREG)
|
||||
yyerror("bad addressing modes");
|
||||
reg = g2->scale;
|
||||
}
|
||||
|
||||
p = ctxt->arch->prg();
|
||||
p->as = a;
|
||||
p->lineno = lineno;
|
||||
if(nosched)
|
||||
p->mark |= NOSCHED;
|
||||
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++;
|
||||
}
|
||||
|
||||
void
|
||||
outgcode(int a, Addr *g1, int reg, Addr *g2, Addr *g3)
|
||||
{
|
||||
Prog *p;
|
||||
Plist *pl;
|
||||
|
||||
if(pass == 1)
|
||||
goto out;
|
||||
|
||||
p = ctxt->arch->prg();
|
||||
p->as = a;
|
||||
p->lineno = lineno;
|
||||
if(nosched)
|
||||
p->mark |= NOSCHED;
|
||||
p->from = *g1;
|
||||
p->reg = reg;
|
||||
p->from3 = *g2;
|
||||
p->to = *g3;
|
||||
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"
|
||||
3398
src/cmd/9a/y.tab.c
3398
src/cmd/9a/y.tab.c
File diff suppressed because it is too large
Load Diff
@@ -1,188 +0,0 @@
|
||||
/* A Bison parser, made by GNU Bison 2.3. */
|
||||
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
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. */
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
LMOVW = 258,
|
||||
LMOVB = 259,
|
||||
LABS = 260,
|
||||
LLOGW = 261,
|
||||
LSHW = 262,
|
||||
LADDW = 263,
|
||||
LCMP = 264,
|
||||
LCROP = 265,
|
||||
LBRA = 266,
|
||||
LFMOV = 267,
|
||||
LFCONV = 268,
|
||||
LFCMP = 269,
|
||||
LFADD = 270,
|
||||
LFMA = 271,
|
||||
LTRAP = 272,
|
||||
LXORW = 273,
|
||||
LNOP = 274,
|
||||
LEND = 275,
|
||||
LRETT = 276,
|
||||
LWORD = 277,
|
||||
LTEXT = 278,
|
||||
LDATA = 279,
|
||||
LRETRN = 280,
|
||||
LCONST = 281,
|
||||
LSP = 282,
|
||||
LSB = 283,
|
||||
LFP = 284,
|
||||
LPC = 285,
|
||||
LCREG = 286,
|
||||
LFLUSH = 287,
|
||||
LREG = 288,
|
||||
LFREG = 289,
|
||||
LR = 290,
|
||||
LCR = 291,
|
||||
LF = 292,
|
||||
LFPSCR = 293,
|
||||
LLR = 294,
|
||||
LCTR = 295,
|
||||
LSPR = 296,
|
||||
LSPREG = 297,
|
||||
LSEG = 298,
|
||||
LMSR = 299,
|
||||
LPCDAT = 300,
|
||||
LFUNCDAT = 301,
|
||||
LSCHED = 302,
|
||||
LXLD = 303,
|
||||
LXST = 304,
|
||||
LXOP = 305,
|
||||
LXMV = 306,
|
||||
LRLWM = 307,
|
||||
LMOVMW = 308,
|
||||
LMOVEM = 309,
|
||||
LMOVFL = 310,
|
||||
LMTFSB = 311,
|
||||
LMA = 312,
|
||||
LFCONST = 313,
|
||||
LSCONST = 314,
|
||||
LNAME = 315,
|
||||
LLAB = 316,
|
||||
LVAR = 317
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define LMOVW 258
|
||||
#define LMOVB 259
|
||||
#define LABS 260
|
||||
#define LLOGW 261
|
||||
#define LSHW 262
|
||||
#define LADDW 263
|
||||
#define LCMP 264
|
||||
#define LCROP 265
|
||||
#define LBRA 266
|
||||
#define LFMOV 267
|
||||
#define LFCONV 268
|
||||
#define LFCMP 269
|
||||
#define LFADD 270
|
||||
#define LFMA 271
|
||||
#define LTRAP 272
|
||||
#define LXORW 273
|
||||
#define LNOP 274
|
||||
#define LEND 275
|
||||
#define LRETT 276
|
||||
#define LWORD 277
|
||||
#define LTEXT 278
|
||||
#define LDATA 279
|
||||
#define LRETRN 280
|
||||
#define LCONST 281
|
||||
#define LSP 282
|
||||
#define LSB 283
|
||||
#define LFP 284
|
||||
#define LPC 285
|
||||
#define LCREG 286
|
||||
#define LFLUSH 287
|
||||
#define LREG 288
|
||||
#define LFREG 289
|
||||
#define LR 290
|
||||
#define LCR 291
|
||||
#define LF 292
|
||||
#define LFPSCR 293
|
||||
#define LLR 294
|
||||
#define LCTR 295
|
||||
#define LSPR 296
|
||||
#define LSPREG 297
|
||||
#define LSEG 298
|
||||
#define LMSR 299
|
||||
#define LPCDAT 300
|
||||
#define LFUNCDAT 301
|
||||
#define LSCHED 302
|
||||
#define LXLD 303
|
||||
#define LXST 304
|
||||
#define LXOP 305
|
||||
#define LXMV 306
|
||||
#define LRLWM 307
|
||||
#define LMOVMW 308
|
||||
#define LMOVEM 309
|
||||
#define LMOVFL 310
|
||||
#define LMTFSB 311
|
||||
#define LMA 312
|
||||
#define LFCONST 313
|
||||
#define LSCONST 314
|
||||
#define LNAME 315
|
||||
#define LLAB 316
|
||||
#define LVAR 317
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE
|
||||
#line 38 "a.y"
|
||||
{
|
||||
Sym *sym;
|
||||
vlong lval;
|
||||
double dval;
|
||||
char sval[8];
|
||||
Addr addr;
|
||||
}
|
||||
/* Line 1529 of yacc.c. */
|
||||
#line 181 "y.tab.h"
|
||||
YYSTYPE;
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# Copyright 2012 The Go Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
include ../../Make.dist
|
||||
@@ -1,14 +0,0 @@
|
||||
- effect of register expansion on 32-bit shifts and masks etc
|
||||
9c
|
||||
- multab
|
||||
- floating-point conversions
|
||||
- conversions of constants
|
||||
- nodtype for loads
|
||||
- sign-extension instruction (32-64) when in register?
|
||||
- double indexing
|
||||
- SLW (eg, in cat)
|
||||
- scheduling
|
||||
|
||||
9l
|
||||
- D_QCONST, DWORD
|
||||
- maskgen
|
||||
1147
src/cmd/9c/cgen.c
1147
src/cmd/9c/cgen.c
File diff suppressed because it is too large
Load Diff
@@ -1,17 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. 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
|
||||
|
||||
/*
|
||||
|
||||
9c 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 Power64, referred to by these tools as
|
||||
power64 (big endian) or power64le (little endian).
|
||||
|
||||
*/
|
||||
package main
|
||||
350
src/cmd/9c/gc.h
350
src/cmd/9c/gc.h
@@ -1,350 +0,0 @@
|
||||
// cmd/9c/gc.h from Vita Nuova.
|
||||
//
|
||||
// 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-2008 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-2008 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 "../9l/9.out.h"
|
||||
|
||||
/*
|
||||
* 9c/powerpc64
|
||||
*/
|
||||
#define SZ_CHAR 1
|
||||
#define SZ_SHORT 2
|
||||
#define SZ_INT 4
|
||||
#define SZ_LONG 4
|
||||
#define SZ_IND 8
|
||||
#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 A ((Adr*)0)
|
||||
|
||||
#define INDEXED 9
|
||||
#define P ((Prog*)0)
|
||||
|
||||
struct Case
|
||||
{
|
||||
Case* link;
|
||||
vlong val;
|
||||
int32 label;
|
||||
char def;
|
||||
char isv;
|
||||
};
|
||||
#define C ((Case*)0)
|
||||
|
||||
struct C1
|
||||
{
|
||||
vlong 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 */
|
||||
|
||||
union
|
||||
{
|
||||
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 Node vconstnode;
|
||||
EXTERN int32 continpc;
|
||||
EXTERN int32 curarg;
|
||||
EXTERN int32 cursafe;
|
||||
EXTERN Prog* lastp;
|
||||
extern int hintabsize;
|
||||
EXTERN int32 maxargsafe;
|
||||
EXTERN Multab multab[20];
|
||||
EXTERN int mnstring;
|
||||
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 Node qregnode;
|
||||
EXTERN char string[NSNAME];
|
||||
EXTERN Sym* symrathole;
|
||||
EXTERN Node znode;
|
||||
EXTERN Prog zprog;
|
||||
EXTERN int reg[NREG+NREG];
|
||||
EXTERN int32 exregoffset;
|
||||
EXTERN int32 exfregoffset;
|
||||
EXTERN uchar typechlpv[NTYPE];
|
||||
|
||||
#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 5
|
||||
#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 int suppress;
|
||||
|
||||
EXTERN Reg* firstr;
|
||||
EXTERN Reg* lastr;
|
||||
EXTERN Reg zreg;
|
||||
EXTERN Reg* freer;
|
||||
EXTERN Var var[NVAR];
|
||||
EXTERN int32* idom;
|
||||
EXTERN Reg** rpo2r;
|
||||
EXTERN int32 maxnr;
|
||||
|
||||
#define R0ISZERO (debug['0']==0)
|
||||
|
||||
extern char* anames[];
|
||||
extern Hintab hintab[];
|
||||
|
||||
/*
|
||||
* sgen.c
|
||||
*/
|
||||
void codgen(Node*, Node*);
|
||||
void gen(Node*);
|
||||
void usedset(Node*, int);
|
||||
void noretval(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*);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
Node* nodgconst(vlong v, Type *t);
|
||||
void nodreg(Node*, Node*, int);
|
||||
void regret(Node*, Node*, Type*, int);
|
||||
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 gmove(Node*, Node*);
|
||||
void gins(int a, Node*, Node*);
|
||||
void gopcode(int, Node*, Node*, Node*);
|
||||
int samaddr(Node*, Node*);
|
||||
void gbranch(int);
|
||||
int immconst(Node*);
|
||||
void patch(Prog*, int32);
|
||||
int sconst(Node*);
|
||||
int sval(int32);
|
||||
int uconst(Node*);
|
||||
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*, Node*);
|
||||
void newcase(void);
|
||||
void bitload(Node*, Node*, Node*, Node*, Node*);
|
||||
void bitstore(Node*, Node*, Node*, Node*, Node*);
|
||||
int32 outstring(char*, int32);
|
||||
int mulcon(Node*, Node*);
|
||||
Multab* mulcon0(Node*, int32);
|
||||
int mulcon1(Node*, int32, Node*);
|
||||
void nullwarn(Node*, Node*);
|
||||
void sextern(Sym*, Node*, int32, int32);
|
||||
void gextern(Sym*, Node*, int32, int32);
|
||||
void outcode(void);
|
||||
|
||||
/*
|
||||
* list
|
||||
*/
|
||||
void listinit(void);
|
||||
int Pconv(Fmt*);
|
||||
int Aconv(Fmt*);
|
||||
int Dconv(Fmt*);
|
||||
int Sconv(Fmt*);
|
||||
int Nconv(Fmt*);
|
||||
int Bconv(Fmt*);
|
||||
|
||||
/*
|
||||
* 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 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);
|
||||
|
||||
/*
|
||||
* com64.c
|
||||
*/
|
||||
int com64(Node*);
|
||||
void com64init(void);
|
||||
void bool64(Node*);
|
||||
|
||||
#pragma varargck type "A" int
|
||||
#pragma varargck type "B" Bits
|
||||
#pragma varargck type "D" Addr*
|
||||
#pragma varargck type "N" Addr*
|
||||
#pragma varargck type "P" Prog*
|
||||
#pragma varargck type "S" char*
|
||||
@@ -1,37 +0,0 @@
|
||||
// cmd/9c/list.c from Vita Nuova.
|
||||
//
|
||||
// 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-2008 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-2008 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 "gc.h"
|
||||
|
||||
void
|
||||
listinit(void)
|
||||
{
|
||||
listinit9();
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
// cmd/9c/machcap.c from Vita Nuova.
|
||||
//
|
||||
// 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-2008 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-2008 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"
|
||||
|
||||
int
|
||||
machcap(Node *n)
|
||||
{
|
||||
|
||||
if(n == Z)
|
||||
return 1; /* test */
|
||||
|
||||
switch(n->op) {
|
||||
case OMUL:
|
||||
case OLMUL:
|
||||
case OASMUL:
|
||||
case OASLMUL:
|
||||
if(typechlv[n->type->etype])
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case OADD:
|
||||
case OAND:
|
||||
case OOR:
|
||||
case OSUB:
|
||||
case OXOR:
|
||||
case OASHL:
|
||||
case OLSHR:
|
||||
case OASHR:
|
||||
if(typechlv[n->left->type->etype])
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case OCAST:
|
||||
return 1;
|
||||
|
||||
case OCOND:
|
||||
case OCOMMA:
|
||||
case OLIST:
|
||||
case OANDAND:
|
||||
case OOROR:
|
||||
case ONOT:
|
||||
return 1;
|
||||
|
||||
case OASADD:
|
||||
case OASSUB:
|
||||
case OASAND:
|
||||
case OASOR:
|
||||
case OASXOR:
|
||||
return 1;
|
||||
|
||||
case OASASHL:
|
||||
case OASASHR:
|
||||
case OASLSHR:
|
||||
return 1;
|
||||
|
||||
case OPOSTINC:
|
||||
case OPOSTDEC:
|
||||
case OPREINC:
|
||||
case OPREDEC:
|
||||
return 1;
|
||||
|
||||
case OEQ:
|
||||
case ONE:
|
||||
case OLE:
|
||||
case OGT:
|
||||
case OLT:
|
||||
case OGE:
|
||||
case OHI:
|
||||
case OHS:
|
||||
case OLO:
|
||||
case OLS:
|
||||
return 1;
|
||||
case ONEG:
|
||||
case OCOM:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
638
src/cmd/9c/mul.c
638
src/cmd/9c/mul.c
@@ -1,638 +0,0 @@
|
||||
// cmd/9c/mul.c from Vita Nuova.
|
||||
//
|
||||
// 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-2008 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-2008 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 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(Node *n, 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("%L: multiply table failure %ld\n", n->lineno, v);
|
||||
m->code[0] = 0;
|
||||
return 0;
|
||||
|
||||
no:
|
||||
/*
|
||||
* try to search
|
||||
*/
|
||||
hint[0] = 0;
|
||||
for(g=1; g<=6; g++) {
|
||||
if(g >= 6 && v >= 65535)
|
||||
break;
|
||||
mulcp = hint+g;
|
||||
*mulcp = 0;
|
||||
if(gen1(g)) {
|
||||
if(docode(hint, m->code, 1, 0))
|
||||
return m;
|
||||
print("%L: multiply table failure (g=%d h=%s) %ld\n",
|
||||
n->lineno, g, hint, v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* try a recur followed by a shift
|
||||
*/
|
||||
g = 0;
|
||||
while(!(v & 1)) {
|
||||
g++;
|
||||
v >>= 1;
|
||||
}
|
||||
if(g) {
|
||||
m1 = mulcon0(n, 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);
|
||||
1076
src/cmd/9c/peep.c
1076
src/cmd/9c/peep.c
File diff suppressed because it is too large
Load Diff
1163
src/cmd/9c/reg.c
1163
src/cmd/9c/reg.c
File diff suppressed because it is too large
Load Diff
@@ -1,291 +0,0 @@
|
||||
// cmd/9c/sgen.c from Vita Nuova.
|
||||
//
|
||||
// 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-2008 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-2008 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)
|
||||
{
|
||||
vlong v;
|
||||
|
||||
v = ((uvlong)argsize(1) << 32) | (stkoff & 0xffffffff);
|
||||
if((textflag & NOSPLIT) && stkoff >= 128)
|
||||
yyerror("stack frame too large for NOSPLIT function");
|
||||
|
||||
gpseudo(ATEXT, s, nodgconst(v, types[TVLONG]));
|
||||
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 v;
|
||||
|
||||
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 OASMUL:
|
||||
case OASLMUL:
|
||||
xcom(l);
|
||||
xcom(r);
|
||||
v = vlog(r);
|
||||
if(v >= 0) {
|
||||
n->op = OASASHL;
|
||||
r->vconst = v;
|
||||
r->type = types[TINT];
|
||||
}
|
||||
break;
|
||||
|
||||
case OMUL:
|
||||
case OLMUL:
|
||||
xcom(l);
|
||||
xcom(r);
|
||||
v = vlog(r);
|
||||
if(v >= 0) {
|
||||
n->op = OASHL;
|
||||
r->vconst = v;
|
||||
r->type = types[TINT];
|
||||
}
|
||||
v = vlog(l);
|
||||
if(v >= 0) {
|
||||
n->op = OASHL;
|
||||
n->left = r;
|
||||
n->right = l;
|
||||
r = l;
|
||||
l = n->left;
|
||||
r->vconst = v;
|
||||
r->type = types[TINT];
|
||||
simplifyshift(n);
|
||||
}
|
||||
break;
|
||||
|
||||
case OASLDIV:
|
||||
xcom(l);
|
||||
xcom(r);
|
||||
v = vlog(r);
|
||||
if(v >= 0) {
|
||||
n->op = OASLSHR;
|
||||
r->vconst = v;
|
||||
r->type = types[TINT];
|
||||
}
|
||||
break;
|
||||
|
||||
case OLDIV:
|
||||
xcom(l);
|
||||
xcom(r);
|
||||
v = vlog(r);
|
||||
if(v >= 0) {
|
||||
n->op = OLSHR;
|
||||
r->vconst = v;
|
||||
r->type = types[TINT];
|
||||
simplifyshift(n);
|
||||
}
|
||||
break;
|
||||
|
||||
case OASLMOD:
|
||||
xcom(l);
|
||||
xcom(r);
|
||||
v = vlog(r);
|
||||
if(v >= 0) {
|
||||
n->op = OASAND;
|
||||
r->vconst--;
|
||||
}
|
||||
break;
|
||||
|
||||
case OLMOD:
|
||||
xcom(l);
|
||||
xcom(r);
|
||||
v = vlog(r);
|
||||
if(v >= 0) {
|
||||
n->op = OAND;
|
||||
r->vconst--;
|
||||
}
|
||||
break;
|
||||
|
||||
case OLSHR:
|
||||
case OASHL:
|
||||
case OASHR:
|
||||
xcom(l);
|
||||
xcom(r);
|
||||
simplifyshift(n);
|
||||
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 OEQ:
|
||||
case ONE:
|
||||
case OLE:
|
||||
case OLT:
|
||||
case OGE:
|
||||
case OGT:
|
||||
case OHI:
|
||||
case OHS:
|
||||
case OLO:
|
||||
case OLS:
|
||||
/*
|
||||
* immediate operators, make const on right
|
||||
*/
|
||||
if(l->op == OCONST) {
|
||||
n->left = r;
|
||||
n->right = l;
|
||||
n->op = invrel[relindex(n->op)];
|
||||
}
|
||||
break;
|
||||
|
||||
case OADD:
|
||||
case OXOR:
|
||||
case OAND:
|
||||
case OOR:
|
||||
/*
|
||||
* immediate operators, make const on right
|
||||
*/
|
||||
if(l->op == OCONST) {
|
||||
n->left = r;
|
||||
n->right = l;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
407
src/cmd/9c/swt.c
407
src/cmd/9c/swt.c
@@ -1,407 +0,0 @@
|
||||
// cmd/9c/swt.c from Vita Nuova.
|
||||
//
|
||||
// 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-2008 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-2008 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 tn, nod;
|
||||
|
||||
regalloc(&nod, n, Z);
|
||||
/* always signed */
|
||||
if(typev[n->type->etype])
|
||||
nod.type = types[TVLONG];
|
||||
else
|
||||
nod.type = types[TLONG];
|
||||
cgen(n, &nod);
|
||||
regalloc(&tn, ®node, Z);
|
||||
swit2(q, nc, def, &nod, &tn);
|
||||
regfree(&tn);
|
||||
regfree(&nod);
|
||||
}
|
||||
|
||||
void
|
||||
swit2(C1 *q, int nc, int32 def, Node *n, Node *tn)
|
||||
{
|
||||
C1 *r;
|
||||
int i;
|
||||
Prog *sp;
|
||||
|
||||
if(nc < 5) {
|
||||
for(i=0; i<nc; i++) {
|
||||
if(sval(q->val)) {
|
||||
gopcode(OEQ, n, Z, nodconst(q->val));
|
||||
} else {
|
||||
gopcode(OSUB, nodconst(q->val), n, tn);
|
||||
gopcode(OEQ, tn, Z, nodconst(0));
|
||||
}
|
||||
patch(p, q->label);
|
||||
q++;
|
||||
}
|
||||
gbranch(OGOTO);
|
||||
patch(p, def);
|
||||
return;
|
||||
}
|
||||
i = nc / 2;
|
||||
r = q+i;
|
||||
if(sval(r->val)) {
|
||||
gopcode(OGT, n, Z, nodconst(r->val));
|
||||
sp = p;
|
||||
} else {
|
||||
gopcode(OSUB, nodconst(r->val), n, tn);
|
||||
gopcode(OGT, tn, Z, nodconst(0));
|
||||
sp = p;
|
||||
}
|
||||
gbranch(OGOTO);
|
||||
p->as = ABEQ;
|
||||
patch(p, r->label);
|
||||
swit2(q, i, def, n, tn);
|
||||
|
||||
patch(sp, pc);
|
||||
swit2(r+1, nc-i-1, def, n, tn);
|
||||
}
|
||||
|
||||
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;
|
||||
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(n, v);
|
||||
if(!m) {
|
||||
if(debug['M'])
|
||||
print("%L multiply table: %lld\n", n->lineno, r->vconst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
if(v < 0)
|
||||
gopcode(ONEG, &nod1, Z, &nod1);
|
||||
regalloc(&nod2, n, Z);
|
||||
|
||||
loop:
|
||||
switch(*p) {
|
||||
case 0:
|
||||
regfree(&nod2);
|
||||
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)
|
||||
{
|
||||
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 = nil;
|
||||
}
|
||||
|
||||
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 allign 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 < 1 || w > SZ_VLONG)
|
||||
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(typesu[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_VLONG) {
|
||||
w = SZ_VLONG;
|
||||
break;
|
||||
}
|
||||
w = 1;
|
||||
break;
|
||||
|
||||
case Aarg2: /* width of a parameter */
|
||||
o += t->width;
|
||||
w = t->width;
|
||||
if(w > SZ_VLONG)
|
||||
w = SZ_VLONG;
|
||||
break;
|
||||
|
||||
case Aaut3: /* total align of automatic */
|
||||
o = align(o, t, Ael1, nil);
|
||||
o = align(o, t, Ael2, nil);
|
||||
break;
|
||||
}
|
||||
if(packw != 0 && xround(o, w) != xround(o, packw))
|
||||
diag(Z, "#pragma pack changes offset of %T", t);
|
||||
o = xround(o, w);
|
||||
if(maxalign && *maxalign < w)
|
||||
*maxalign = w;
|
||||
if(debug['A'])
|
||||
print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
|
||||
return o;
|
||||
}
|
||||
|
||||
int32
|
||||
maxround(int32 max, int32 v)
|
||||
{
|
||||
v = xround(v, SZ_VLONG);
|
||||
if(v > max)
|
||||
return v;
|
||||
return max;
|
||||
}
|
||||
1537
src/cmd/9c/txt.c
1537
src/cmd/9c/txt.c
File diff suppressed because it is too large
Load Diff
1763
src/cmd/9g/cgen.c
1763
src/cmd/9g/cgen.c
File diff suppressed because it is too large
Load Diff
@@ -1,16 +0,0 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build ignore
|
||||
|
||||
/*
|
||||
|
||||
9g is the version of the gc compiler for the Power64.
|
||||
The $GOARCH for these tools is power64 (big endian) or
|
||||
power64le (little endian).
|
||||
|
||||
It reads .go files and outputs .9 files. The flags are documented in ../gc/doc.go.
|
||||
|
||||
*/
|
||||
package main
|
||||
@@ -1,54 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "gg.h"
|
||||
|
||||
int thechar = '9';
|
||||
char* thestring = "power64";
|
||||
LinkArch* thelinkarch;
|
||||
|
||||
void
|
||||
linkarchinit(void)
|
||||
{
|
||||
thestring = getgoarch();
|
||||
if(strcmp(thestring, "power64le") == 0)
|
||||
thelinkarch = &linkpower64le;
|
||||
else
|
||||
thelinkarch = &linkpower64;
|
||||
}
|
||||
|
||||
vlong MAXWIDTH = 1LL<<50;
|
||||
|
||||
/*
|
||||
* go declares several platform-specific type aliases:
|
||||
* int, uint, float, and uintptr
|
||||
*/
|
||||
Typedef typedefs[] =
|
||||
{
|
||||
{"int", TINT, TINT64},
|
||||
{"uint", TUINT, TUINT64},
|
||||
{"uintptr", TUINTPTR, TUINT64},
|
||||
{0}
|
||||
};
|
||||
|
||||
void
|
||||
betypeinit(void)
|
||||
{
|
||||
widthptr = 8;
|
||||
widthint = 8;
|
||||
widthreg = 8;
|
||||
|
||||
zprog.link = P;
|
||||
zprog.as = AGOK;
|
||||
zprog.reg = NREG;
|
||||
zprog.from.name = D_NONE;
|
||||
zprog.from.type = D_NONE;
|
||||
zprog.from.reg = NREG;
|
||||
zprog.to = zprog.from;
|
||||
zprog.from3 = zprog.from;
|
||||
|
||||
listinit9();
|
||||
}
|
||||
117
src/cmd/9g/gg.h
117
src/cmd/9g/gg.h
@@ -1,117 +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.
|
||||
|
||||
#ifndef EXTERN
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#include "../gc/go.h"
|
||||
#include "../9l/9.out.h"
|
||||
|
||||
// TODO(minux): Remove when no longer used.
|
||||
#define noimpl sysfatal("%s not implemented (%s:%d).", __func__, __FILE__, __LINE__)
|
||||
|
||||
#define TEXTFLAG reg
|
||||
|
||||
EXTERN int32 dynloc;
|
||||
EXTERN uchar reg[NREG+NFREG];
|
||||
EXTERN int32 pcloc; // instruction counter
|
||||
EXTERN Strlit emptystring;
|
||||
EXTERN Prog zprog;
|
||||
EXTERN Node* newproc;
|
||||
EXTERN Node* deferproc;
|
||||
EXTERN Node* deferreturn;
|
||||
EXTERN Node* panicindex;
|
||||
EXTERN Node* panicslice;
|
||||
EXTERN Node* panicdiv;
|
||||
EXTERN Node* throwreturn;
|
||||
extern vlong unmappedzero;
|
||||
|
||||
/*
|
||||
* ggen.c
|
||||
*/
|
||||
void compile(Node*);
|
||||
void gen(Node*);
|
||||
Node* lookdot(Node*, Node*, int);
|
||||
void cgen_as(Node*, Node*);
|
||||
void cgen_callmeth(Node*, int);
|
||||
void cgen_callinter(Node*, Node*, int);
|
||||
void cgen_proc(Node*, int);
|
||||
void cgen_callret(Node*, Node*);
|
||||
void cgen_div(int, Node*, Node*, Node*);
|
||||
void cgen_hmul(Node*, Node*, Node*);
|
||||
void cgen_shift(int, int, Node*, Node*, Node*);
|
||||
void cgen_dcl(Node*);
|
||||
int needconvert(Type*, Type*);
|
||||
void genconv(Type*, Type*);
|
||||
void allocparams(void);
|
||||
void checklabels(void);
|
||||
void ginscall(Node*, int);
|
||||
int gen_as_init(Node*);
|
||||
|
||||
/*
|
||||
* cgen.c
|
||||
*/
|
||||
void agen(Node*, Node*);
|
||||
void agenr(Node*, Node*, Node*);
|
||||
void cgenr(Node*, Node*, Node*);
|
||||
void igen(Node*, Node*, Node*);
|
||||
vlong fieldoffset(Type*, Node*);
|
||||
void sgen(Node*, Node*, int64);
|
||||
void gmove(Node*, Node*);
|
||||
Prog* gins(int, Node*, Node*);
|
||||
void naddr(Node*, Addr*, int);
|
||||
void cgen_aret(Node*, Node*);
|
||||
int componentgen(Node*, Node*);
|
||||
|
||||
/*
|
||||
* gsubr.c
|
||||
*/
|
||||
void clearp(Prog*);
|
||||
Prog* gbranch(int, Type*, int);
|
||||
Prog* prog(int);
|
||||
void gconv(int, int);
|
||||
int conv2pt(Type*);
|
||||
vlong convvtox(vlong, int);
|
||||
void fnparam(Type*, int, int);
|
||||
Prog* gop(int, Node*, Node*, Node*);
|
||||
int optoas(int, Type*);
|
||||
void ginit(void);
|
||||
void gclean(void);
|
||||
void regalloc(Node*, Type*, Node*);
|
||||
void regfree(Node*);
|
||||
Node* nodarg(Type*, int);
|
||||
void nodreg(Node*, Type*, int);
|
||||
void nodindreg(Node*, Type*, int);
|
||||
void ginscon(int, vlong, Node*);
|
||||
void ginscon2(int, Node*, vlong);
|
||||
void buildtxt(void);
|
||||
Plist* newplist(void);
|
||||
int isfat(Type*);
|
||||
void sudoclean(void);
|
||||
int sudoaddable(int, Node*, Addr*);
|
||||
void afunclit(Addr*, Node*);
|
||||
void nodfconst(Node*, Type*, Mpflt*);
|
||||
void gtrack(Sym*);
|
||||
void fixlargeoffset(Node *n);
|
||||
|
||||
/*
|
||||
* cplx.c
|
||||
*/
|
||||
int complexop(Node*, Node*);
|
||||
void complexmove(Node*, Node*);
|
||||
void complexgen(Node*, Node*);
|
||||
|
||||
/*
|
||||
* gobj.c
|
||||
*/
|
||||
void datastring(char*, int, Addr*);
|
||||
void datagostring(Strlit*, Addr*);
|
||||
|
||||
/*
|
||||
* list.c
|
||||
*/
|
||||
void listinit(void);
|
||||
|
||||
void zaddr(Biobuf*, Addr*, int, int);
|
||||
1040
src/cmd/9g/ggen.c
1040
src/cmd/9g/ggen.c
File diff suppressed because it is too large
Load Diff
@@ -1,240 +0,0 @@
|
||||
// Derived from Inferno utils/6c/swt.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/6c/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 <u.h>
|
||||
#include <libc.h>
|
||||
#include "gg.h"
|
||||
|
||||
int
|
||||
dsname(Sym *s, int off, char *t, int n)
|
||||
{
|
||||
Prog *p;
|
||||
|
||||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_OREG;
|
||||
p->from.name = D_EXTERN;
|
||||
p->from.offset = off;
|
||||
p->from.reg = NREG;
|
||||
p->from.sym = linksym(s);
|
||||
|
||||
p->reg = n;
|
||||
|
||||
p->to.type = D_SCONST;
|
||||
p->to.name = D_NONE;
|
||||
p->to.reg = NREG;
|
||||
p->to.offset = 0;
|
||||
memmove(p->to.u.sval, t, n);
|
||||
return off + n;
|
||||
}
|
||||
|
||||
/*
|
||||
* make a refer to the data s, s+len
|
||||
* emitting DATA if needed.
|
||||
*/
|
||||
void
|
||||
datastring(char *s, int len, Addr *a)
|
||||
{
|
||||
Sym *sym;
|
||||
|
||||
sym = stringsym(s, len);
|
||||
a->type = D_OREG;
|
||||
a->name = D_EXTERN;
|
||||
a->etype = simtype[TINT];
|
||||
a->offset = widthptr+widthint; // skip header
|
||||
a->reg = NREG;
|
||||
a->sym = linksym(sym);
|
||||
a->node = sym->def;
|
||||
}
|
||||
|
||||
/*
|
||||
* make a refer to the string sval,
|
||||
* emitting DATA if needed.
|
||||
*/
|
||||
void
|
||||
datagostring(Strlit *sval, Addr *a)
|
||||
{
|
||||
Sym *sym;
|
||||
|
||||
sym = stringsym(sval->s, sval->len);
|
||||
a->type = D_OREG;
|
||||
a->name = D_EXTERN;
|
||||
a->sym = linksym(sym);
|
||||
a->reg = NREG;
|
||||
a->node = sym->def;
|
||||
a->offset = 0; // header
|
||||
a->etype = TSTRING;
|
||||
}
|
||||
|
||||
void
|
||||
gdata(Node *nam, Node *nr, int wid)
|
||||
{
|
||||
Prog *p;
|
||||
|
||||
if(nr->op == OLITERAL) {
|
||||
switch(nr->val.ctype) {
|
||||
case CTCPLX:
|
||||
gdatacomplex(nam, nr->val.u.cval);
|
||||
return;
|
||||
case CTSTR:
|
||||
gdatastring(nam, nr->val.u.sval);
|
||||
return;
|
||||
}
|
||||
}
|
||||
p = gins(ADATA, nam, nr);
|
||||
p->reg = wid;
|
||||
}
|
||||
|
||||
void
|
||||
gdatacomplex(Node *nam, Mpcplx *cval)
|
||||
{
|
||||
Prog *p;
|
||||
int w;
|
||||
|
||||
w = cplxsubtype(nam->type->etype);
|
||||
w = types[w]->width;
|
||||
|
||||
p = gins(ADATA, nam, N);
|
||||
p->reg = w;
|
||||
p->to.type = D_FCONST;
|
||||
p->to.u.dval = mpgetflt(&cval->real);
|
||||
|
||||
p = gins(ADATA, nam, N);
|
||||
p->reg = w;
|
||||
p->from.offset += w;
|
||||
p->to.type = D_FCONST;
|
||||
p->to.u.dval = mpgetflt(&cval->imag);
|
||||
}
|
||||
|
||||
void
|
||||
gdatastring(Node *nam, Strlit *sval)
|
||||
{
|
||||
Prog *p;
|
||||
Node nod1;
|
||||
|
||||
p = gins(ADATA, nam, N);
|
||||
datastring(sval->s, sval->len, &p->to);
|
||||
p->reg = types[tptr]->width;
|
||||
p->to.type = D_CONST;
|
||||
p->to.etype = simtype[tptr];
|
||||
|
||||
nodconst(&nod1, types[TINT], sval->len);
|
||||
p = gins(ADATA, nam, &nod1);
|
||||
p->reg = widthint;
|
||||
p->from.offset += widthptr;
|
||||
}
|
||||
|
||||
int
|
||||
dstringptr(Sym *s, int off, char *str)
|
||||
{
|
||||
Prog *p;
|
||||
|
||||
off = rnd(off, widthptr);
|
||||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_OREG;
|
||||
p->from.name = D_EXTERN;
|
||||
p->from.sym = linksym(s);
|
||||
p->from.offset = off;
|
||||
p->reg = widthptr;
|
||||
|
||||
datastring(str, strlen(str)+1, &p->to);
|
||||
p->to.type = D_CONST;
|
||||
p->to.etype = simtype[TINT];
|
||||
off += widthptr;
|
||||
|
||||
return off;
|
||||
}
|
||||
|
||||
int
|
||||
dgostrlitptr(Sym *s, int off, Strlit *lit)
|
||||
{
|
||||
Prog *p;
|
||||
|
||||
if(lit == nil)
|
||||
return duintptr(s, off, 0);
|
||||
|
||||
off = rnd(off, widthptr);
|
||||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_OREG;
|
||||
p->from.name = D_EXTERN;
|
||||
p->from.sym = linksym(s);
|
||||
p->from.offset = off;
|
||||
p->reg = widthptr;
|
||||
datagostring(lit, &p->to);
|
||||
p->to.type = D_CONST;
|
||||
p->to.etype = simtype[TINT];
|
||||
off += widthptr;
|
||||
|
||||
return off;
|
||||
}
|
||||
|
||||
int
|
||||
dgostringptr(Sym *s, int off, char *str)
|
||||
{
|
||||
int n;
|
||||
Strlit *lit;
|
||||
|
||||
if(str == nil)
|
||||
return duintptr(s, off, 0);
|
||||
|
||||
n = strlen(str);
|
||||
lit = mal(sizeof *lit + n);
|
||||
strcpy(lit->s, str);
|
||||
lit->len = n;
|
||||
return dgostrlitptr(s, off, lit);
|
||||
}
|
||||
|
||||
int
|
||||
dsymptr(Sym *s, int off, Sym *x, int xoff)
|
||||
{
|
||||
Prog *p;
|
||||
|
||||
off = rnd(off, widthptr);
|
||||
|
||||
p = gins(ADATA, N, N);
|
||||
p->from.type = D_OREG;
|
||||
p->from.name = D_EXTERN;
|
||||
p->from.sym = linksym(s);
|
||||
p->from.offset = off;
|
||||
p->reg = widthptr;
|
||||
p->to.type = D_CONST;
|
||||
p->to.name = D_EXTERN;
|
||||
p->to.sym = linksym(x);
|
||||
p->to.offset = xoff;
|
||||
off += widthptr;
|
||||
|
||||
return off;
|
||||
}
|
||||
|
||||
void
|
||||
nopout(Prog *p)
|
||||
{
|
||||
p->as = ANOP;
|
||||
}
|
||||
|
||||
1707
src/cmd/9g/gsubr.c
1707
src/cmd/9g/gsubr.c
File diff suppressed because it is too large
Load Diff
234
src/cmd/9g/opt.h
234
src/cmd/9g/opt.h
@@ -1,234 +0,0 @@
|
||||
// Derived from Inferno utils/6c/gc.h
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/6c/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 "../gc/popt.h"
|
||||
|
||||
#define Z N
|
||||
#define Adr Addr
|
||||
|
||||
#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 CLOAD 5
|
||||
#define CREF 5
|
||||
#define CINF 1000
|
||||
#define LOOP 3
|
||||
|
||||
typedef struct Reg Reg;
|
||||
typedef struct Rgn Rgn;
|
||||
|
||||
/*c2go
|
||||
extern Node *Z;
|
||||
enum
|
||||
{
|
||||
CLOAD = 5,
|
||||
CREF = 5,
|
||||
CINF = 1000,
|
||||
LOOP = 3,
|
||||
};
|
||||
|
||||
uint32 BLOAD(Reg*);
|
||||
uint32 BSTORE(Reg*);
|
||||
uint32 LOAD(Reg*);
|
||||
uint32 STORE(Reg*);
|
||||
*/
|
||||
|
||||
// A Reg is a wrapper around a single Prog (one instruction) that holds
|
||||
// register optimization information while the optimizer runs.
|
||||
// r->prog is the instruction.
|
||||
// r->prog->opt points back to r.
|
||||
struct Reg
|
||||
{
|
||||
Flow f;
|
||||
|
||||
Bits set; // regopt variables written by this instruction.
|
||||
Bits use1; // regopt variables read by prog->from.
|
||||
Bits use2; // regopt variables read by prog->to.
|
||||
|
||||
// refahead/refbehind are the regopt variables whose current
|
||||
// value may be used in the following/preceding instructions
|
||||
// up to a CALL (or the value is clobbered).
|
||||
Bits refbehind;
|
||||
Bits refahead;
|
||||
// calahead/calbehind are similar, but for variables in
|
||||
// instructions that are reachable after hitting at least one
|
||||
// CALL.
|
||||
Bits calbehind;
|
||||
Bits calahead;
|
||||
Bits regdiff;
|
||||
Bits act;
|
||||
|
||||
uint64 regu; // register used bitmap
|
||||
};
|
||||
#define R ((Reg*)0)
|
||||
/*c2go extern Reg *R; */
|
||||
|
||||
#define NRGN 600
|
||||
/*c2go enum { NRGN = 600 }; */
|
||||
|
||||
// A Rgn represents a single regopt variable over a region of code
|
||||
// where a register could potentially be dedicated to that variable.
|
||||
// The code encompassed by a Rgn is defined by the flow graph,
|
||||
// starting at enter, flood-filling forward while varno is refahead
|
||||
// and backward while varno is refbehind, and following branches. A
|
||||
// single variable may be represented by multiple disjoint Rgns and
|
||||
// each Rgn may choose a different register for that variable.
|
||||
// Registers are allocated to regions greedily in order of descending
|
||||
// cost.
|
||||
struct Rgn
|
||||
{
|
||||
Reg* enter;
|
||||
short cost;
|
||||
short varno;
|
||||
short regno;
|
||||
};
|
||||
|
||||
EXTERN int32 exregoffset; // not set
|
||||
EXTERN int32 exfregoffset; // not set
|
||||
EXTERN Reg zreg;
|
||||
EXTERN Rgn region[NRGN];
|
||||
EXTERN Rgn* rgp;
|
||||
EXTERN int nregion;
|
||||
EXTERN int nvar;
|
||||
EXTERN int32 regbits;
|
||||
EXTERN int32 exregbits; // TODO(austin) not used; remove
|
||||
EXTERN Bits externs;
|
||||
EXTERN Bits params;
|
||||
EXTERN Bits consts;
|
||||
EXTERN Bits addrs;
|
||||
EXTERN Bits ivar;
|
||||
EXTERN Bits ovar;
|
||||
EXTERN int change;
|
||||
EXTERN int32 maxnr;
|
||||
|
||||
EXTERN struct
|
||||
{
|
||||
int32 ncvtreg;
|
||||
int32 nspill;
|
||||
int32 ndelmov;
|
||||
int32 nvar;
|
||||
} ostats;
|
||||
|
||||
/*
|
||||
* reg.c
|
||||
*/
|
||||
int rcmp(const void*, const void*);
|
||||
void regopt(Prog*);
|
||||
void addmove(Reg*, int, int, int);
|
||||
Bits mkvar(Reg*, Adr*);
|
||||
void prop(Reg*, Bits, Bits);
|
||||
void synch(Reg*, Bits);
|
||||
uint64 allreg(uint64, Rgn*);
|
||||
void paint1(Reg*, int);
|
||||
uint64 paint2(Reg*, int, int);
|
||||
void paint3(Reg*, int, uint64, int);
|
||||
void addreg(Adr*, int);
|
||||
void dumpone(Flow*, int);
|
||||
void dumpit(char*, Flow*, int);
|
||||
|
||||
/*
|
||||
* peep.c
|
||||
*/
|
||||
void peep(Prog*);
|
||||
void excise(Flow*);
|
||||
int copyu(Prog*, Adr*, Adr*);
|
||||
|
||||
uint64 RtoB(int);
|
||||
uint64 FtoB(int);
|
||||
int BtoR(uint64);
|
||||
int BtoF(uint64);
|
||||
|
||||
/*
|
||||
* prog.c
|
||||
*/
|
||||
typedef struct ProgInfo ProgInfo;
|
||||
struct ProgInfo
|
||||
{
|
||||
uint32 flags; // the bits below
|
||||
uint64 reguse; // registers implicitly used by this instruction
|
||||
uint64 regset; // registers implicitly set by this instruction
|
||||
uint64 regindex; // registers used by addressing mode
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
// Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA.
|
||||
Pseudo = 1<<1,
|
||||
|
||||
// There's nothing to say about the instruction,
|
||||
// but it's still okay to see.
|
||||
OK = 1<<2,
|
||||
|
||||
// Size of right-side write, or right-side read if no write.
|
||||
SizeB = 1<<3,
|
||||
SizeW = 1<<4,
|
||||
SizeL = 1<<5,
|
||||
SizeQ = 1<<6,
|
||||
SizeF = 1<<7, // float aka float32
|
||||
SizeD = 1<<8, // double aka float64
|
||||
|
||||
// Left side (Prog.from): address taken, read, write.
|
||||
LeftAddr = 1<<9,
|
||||
LeftRead = 1<<10,
|
||||
LeftWrite = 1<<11,
|
||||
|
||||
// Register in middle (Prog.reg); only ever read.
|
||||
RegRead = 1<<12,
|
||||
CanRegRead = 1<<13,
|
||||
|
||||
// Right side (Prog.to): address taken, read, write.
|
||||
RightAddr = 1<<14,
|
||||
RightRead = 1<<15,
|
||||
RightWrite = 1<<16,
|
||||
|
||||
// Instruction updates whichever of from/to is type D_OREG
|
||||
PostInc = 1<<17,
|
||||
|
||||
// Instruction kinds
|
||||
Move = 1<<18, // straight move
|
||||
Conv = 1<<19, // size conversion
|
||||
Cjmp = 1<<20, // conditional jump
|
||||
Break = 1<<21, // breaks control flow (no fallthrough)
|
||||
Call = 1<<22, // function call
|
||||
Jump = 1<<23, // jump
|
||||
Skip = 1<<24, // data instruction
|
||||
};
|
||||
|
||||
void proginfo(ProgInfo*, Prog*);
|
||||
|
||||
// To allow use of AJMP, ACALL, ARET in ../gc/popt.c.
|
||||
enum
|
||||
{
|
||||
AJMP = ABR,
|
||||
ACALL = ABL,
|
||||
ARET = ARETURN,
|
||||
};
|
||||
@@ -1,96 +0,0 @@
|
||||
// Derived from Inferno utils/6c/peep.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/6c/peep.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 <u.h>
|
||||
#include <libc.h>
|
||||
#include "gg.h"
|
||||
#include "opt.h"
|
||||
|
||||
void
|
||||
peep(Prog *p)
|
||||
{
|
||||
USED(p);
|
||||
// TODO(minux)
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
excise(Flow *r)
|
||||
{
|
||||
Prog *p, *l;
|
||||
|
||||
p = r->prog;
|
||||
if(debug['P'] && debug['v'])
|
||||
print("%P ===delete===\n", p);
|
||||
l = p->link;
|
||||
*p = zprog;
|
||||
p->as = ANOP;
|
||||
p->link = l;
|
||||
ostats.ndelmov++;
|
||||
}
|
||||
|
||||
int
|
||||
regtyp(Adr *a)
|
||||
{
|
||||
switch(a->type) {
|
||||
default:
|
||||
return 0;
|
||||
case D_REG:
|
||||
case D_FREG:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
sameaddr(Addr *a, Addr *v)
|
||||
{
|
||||
if(a->type != v->type)
|
||||
return 0;
|
||||
if(regtyp(v) && a->reg == v->reg)
|
||||
return 1;
|
||||
if(v->type == D_AUTO || v->type == D_PARAM)
|
||||
if(v->offset == a->offset)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
smallindir(Addr *a, Addr *reg)
|
||||
{
|
||||
return reg->type == D_REG && a->type == D_OREG &&
|
||||
a->reg == reg->reg &&
|
||||
0 <= a->offset && a->offset < 4096;
|
||||
}
|
||||
|
||||
int
|
||||
stackaddr(Addr *a)
|
||||
{
|
||||
return a->type == D_REG && a->reg == REGSP;
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include "gg.h"
|
||||
#include "opt.h"
|
||||
|
||||
enum {
|
||||
LeftRdwr = LeftRead | LeftWrite,
|
||||
RightRdwr = RightRead | RightWrite,
|
||||
};
|
||||
|
||||
// This table gives the basic information about instruction
|
||||
// generated by the compiler and processed in the optimizer.
|
||||
// See opt.h for bit definitions.
|
||||
//
|
||||
// Instructions not generated need not be listed.
|
||||
// As an exception to that rule, we typically write down all the
|
||||
// size variants of an operation even if we just use a subset.
|
||||
//
|
||||
// The table is formatted for 8-space tabs.
|
||||
static ProgInfo progtable[ALAST] = {
|
||||
[ATYPE]= {Pseudo | Skip},
|
||||
[ATEXT]= {Pseudo},
|
||||
[AFUNCDATA]= {Pseudo},
|
||||
[APCDATA]= {Pseudo},
|
||||
[AUNDEF]= {Break},
|
||||
[AUSEFIELD]= {OK},
|
||||
[ACHECKNIL]= {LeftRead},
|
||||
[AVARDEF]= {Pseudo | RightWrite},
|
||||
[AVARKILL]= {Pseudo | RightWrite},
|
||||
|
||||
// NOP is an internal no-op that also stands
|
||||
// for USED and SET annotations, not the Power opcode.
|
||||
[ANOP]= {LeftRead | RightWrite},
|
||||
|
||||
// Integer
|
||||
[AADD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||
[ASUB]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||
[ANEG]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||
[AAND]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||
[AOR]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||
[AXOR]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||
[AMULLD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||
[AMULLW]= {SizeL | LeftRead | RegRead | RightWrite},
|
||||
[AMULHD]= {SizeL | LeftRead | RegRead | RightWrite},
|
||||
[AMULHDU]= {SizeL | LeftRead | RegRead | RightWrite},
|
||||
[ADIVD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||
[ADIVDU]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||
[ASLD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||
[ASRD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||
[ASRAD]= {SizeQ | LeftRead | RegRead | RightWrite},
|
||||
[ACMP]= {SizeQ | LeftRead | RightRead},
|
||||
[ACMPU]= {SizeQ | LeftRead | RightRead},
|
||||
[ATD]= {SizeQ | RightRead},
|
||||
|
||||
// Floating point.
|
||||
[AFADD]= {SizeD | LeftRead | RegRead | RightWrite},
|
||||
[AFADDS]= {SizeF | LeftRead | RegRead | RightWrite},
|
||||
[AFSUB]= {SizeD | LeftRead | RegRead | RightWrite},
|
||||
[AFSUBS]= {SizeF | LeftRead | RegRead | RightWrite},
|
||||
[AFMUL]= {SizeD | LeftRead | RegRead | RightWrite},
|
||||
[AFMULS]= {SizeF | LeftRead | RegRead | RightWrite},
|
||||
[AFDIV]= {SizeD | LeftRead | RegRead | RightWrite},
|
||||
[AFDIVS]= {SizeF | LeftRead | RegRead | RightWrite},
|
||||
[AFCTIDZ]= {SizeF | LeftRead | RegRead | RightWrite},
|
||||
[AFCFID]= {SizeF | LeftRead | RegRead | RightWrite},
|
||||
[AFCMPU]= {SizeD | LeftRead | RightRead},
|
||||
[AFRSP]= {SizeD | LeftRead | RightWrite | Conv},
|
||||
|
||||
// Moves
|
||||
[AMOVB]= {SizeB | LeftRead | RightWrite | Move | Conv},
|
||||
[AMOVBU]= {SizeB | LeftRead | RightWrite | Move | Conv | PostInc},
|
||||
[AMOVBZ]= {SizeB | LeftRead | RightWrite | Move | Conv},
|
||||
[AMOVH]= {SizeW | LeftRead | RightWrite | Move | Conv},
|
||||
[AMOVHU]= {SizeW | LeftRead | RightWrite | Move | Conv | PostInc},
|
||||
[AMOVHZ]= {SizeW | LeftRead | RightWrite | Move | Conv},
|
||||
[AMOVW]= {SizeL | LeftRead | RightWrite | Move | Conv},
|
||||
// there is no AMOVWU.
|
||||
[AMOVWZU]= {SizeL | LeftRead | RightWrite | Move | Conv | PostInc},
|
||||
[AMOVWZ]= {SizeL | LeftRead | RightWrite | Move | Conv},
|
||||
[AMOVD]= {SizeQ | LeftRead | RightWrite | Move},
|
||||
[AMOVDU]= {SizeQ | LeftRead | RightWrite | Move | PostInc},
|
||||
[AFMOVS]= {SizeF | LeftRead | RightWrite | Move | Conv},
|
||||
[AFMOVD]= {SizeD | LeftRead | RightWrite | Move},
|
||||
|
||||
// Jumps
|
||||
[ABR]= {Jump | Break},
|
||||
[ABL]= {Call},
|
||||
[ABEQ]= {Cjmp},
|
||||
[ABNE]= {Cjmp},
|
||||
[ABGE]= {Cjmp},
|
||||
[ABLT]= {Cjmp},
|
||||
[ABGT]= {Cjmp},
|
||||
[ABLE]= {Cjmp},
|
||||
[ARETURN]= {Break},
|
||||
|
||||
[ADUFFZERO]= {Call},
|
||||
[ADUFFCOPY]= {Call},
|
||||
};
|
||||
|
||||
void
|
||||
proginfo(ProgInfo *info, Prog *p)
|
||||
{
|
||||
*info = progtable[p->as];
|
||||
if(info->flags == 0) {
|
||||
*info = progtable[AADD];
|
||||
fatal("proginfo: unknown instruction %P", p);
|
||||
}
|
||||
|
||||
if((info->flags & RegRead) && p->reg == NREG) {
|
||||
info->flags &= ~RegRead;
|
||||
info->flags |= /*CanRegRead |*/ RightRead;
|
||||
}
|
||||
|
||||
if((p->from.type == D_OREG || p->from.type == D_CONST) && p->from.reg != NREG) {
|
||||
info->regindex |= RtoB(p->from.reg);
|
||||
if(info->flags & PostInc) {
|
||||
info->regset |= RtoB(p->from.reg);
|
||||
}
|
||||
}
|
||||
if((p->to.type == D_OREG || p->to.type == D_CONST) && p->to.reg != NREG) {
|
||||
info->regindex |= RtoB(p->to.reg);
|
||||
if(info->flags & PostInc) {
|
||||
info->regset |= RtoB(p->to.reg);
|
||||
}
|
||||
}
|
||||
|
||||
if(p->from.type == D_CONST && p->from.sym != nil && (info->flags & LeftRead)) {
|
||||
info->flags &= ~LeftRead;
|
||||
info->flags |= LeftAddr;
|
||||
}
|
||||
|
||||
if(p->as == ADUFFZERO) {
|
||||
info->reguse |= RtoB(0) | RtoB(2);
|
||||
info->regset |= RtoB(2);
|
||||
}
|
||||
if(p->as == ADUFFCOPY) {
|
||||
info->reguse |= RtoB(0) | RtoB(2) | RtoB(3);
|
||||
info->regset |= RtoB(2) | RtoB(3);
|
||||
}
|
||||
}
|
||||
1346
src/cmd/9g/reg.c
1346
src/cmd/9g/reg.c
File diff suppressed because it is too large
Load Diff
@@ -1,516 +0,0 @@
|
||||
// cmd/9c/9.out.h from Vita Nuova.
|
||||
//
|
||||
// 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-2008 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-2008 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.
|
||||
|
||||
/*
|
||||
* powerpc 64
|
||||
*/
|
||||
#define NSNAME 8
|
||||
#define NSYM 50
|
||||
#define NREG 32 /* number of general registers */
|
||||
#define NFREG 32 /* number of floating point registers */
|
||||
|
||||
#include "../ld/textflag.h"
|
||||
|
||||
enum
|
||||
{
|
||||
REGZERO = 0, /* set to zero */
|
||||
REGSP = 1,
|
||||
REGSB = 2,
|
||||
REGRET = 3,
|
||||
REGARG = -1, /* -1 disables passing the first argument in register */
|
||||
REGRT1 = 3, /* reserved for runtime, duffzero and duffcopy */
|
||||
REGRT2 = 4, /* reserved for runtime, duffcopy */
|
||||
REGMIN = 7, /* register variables allocated from here to REGMAX */
|
||||
REGENV = 11, /* environment for closures */
|
||||
REGMAX = 27,
|
||||
REGEXT = 30, /* external registers allocated from here down */
|
||||
REGG = 30, /* G */
|
||||
REGTMP = 31, /* used by the linker */
|
||||
|
||||
FREGRET = 0,
|
||||
FREGMIN = 17, /* first register variable */
|
||||
FREGMAX = 26, /* last register variable for 9g only */
|
||||
FREGEXT = 26, /* first external register */
|
||||
FREGCVI = 27, /* floating conversion constant */
|
||||
FREGZERO = 28, /* both float and double */
|
||||
FREGHALF = 29, /* double */
|
||||
FREGONE = 30, /* double */
|
||||
FREGTWO = 31 /* double */
|
||||
/*
|
||||
* GENERAL:
|
||||
*
|
||||
* compiler allocates R3 up as temps
|
||||
* compiler allocates register variables R7-R27
|
||||
* compiler allocates external registers R30 down
|
||||
*
|
||||
* compiler allocates register variables F17-F26
|
||||
* compiler allocates external registers F26 down
|
||||
*/
|
||||
};
|
||||
|
||||
enum {
|
||||
BIG = 32768-8,
|
||||
};
|
||||
|
||||
enum {
|
||||
/* mark flags */
|
||||
LABEL = 1<<0,
|
||||
LEAF = 1<<1,
|
||||
FLOAT = 1<<2,
|
||||
BRANCH = 1<<3,
|
||||
LOAD = 1<<4,
|
||||
FCMP = 1<<5,
|
||||
SYNC = 1<<6,
|
||||
LIST = 1<<7,
|
||||
FOLL = 1<<8,
|
||||
NOSCHED = 1<<9,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
C_NONE,
|
||||
C_REG,
|
||||
C_FREG,
|
||||
C_CREG,
|
||||
C_SPR, /* special processor register */
|
||||
C_ZCON,
|
||||
C_SCON, /* 16 bit signed */
|
||||
C_UCON, /* low 16 bits 0 */
|
||||
C_ADDCON, /* -0x8000 <= v < 0 */
|
||||
C_ANDCON, /* 0 < v <= 0xFFFF */
|
||||
C_LCON, /* other 32 */
|
||||
C_DCON, /* other 64 (could subdivide further) */
|
||||
C_SACON,
|
||||
C_SECON,
|
||||
C_LACON,
|
||||
C_LECON,
|
||||
C_SBRA,
|
||||
C_LBRA,
|
||||
C_SAUTO,
|
||||
C_LAUTO,
|
||||
C_SEXT,
|
||||
C_LEXT,
|
||||
C_ZOREG,
|
||||
C_SOREG,
|
||||
C_LOREG,
|
||||
C_FPSCR,
|
||||
C_MSR,
|
||||
C_XER,
|
||||
C_LR,
|
||||
C_CTR,
|
||||
C_ANY,
|
||||
C_GOK,
|
||||
C_ADDR,
|
||||
|
||||
C_NCLASS, /* must be the last */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
AXXX,
|
||||
AADD,
|
||||
AADDCC,
|
||||
AADDV,
|
||||
AADDVCC,
|
||||
AADDC,
|
||||
AADDCCC,
|
||||
AADDCV,
|
||||
AADDCVCC,
|
||||
AADDME,
|
||||
AADDMECC,
|
||||
AADDMEVCC,
|
||||
AADDMEV,
|
||||
AADDE,
|
||||
AADDECC,
|
||||
AADDEVCC,
|
||||
AADDEV,
|
||||
AADDZE,
|
||||
AADDZECC,
|
||||
AADDZEVCC,
|
||||
AADDZEV,
|
||||
AAND,
|
||||
AANDCC,
|
||||
AANDN,
|
||||
AANDNCC,
|
||||
ABC,
|
||||
ABCL,
|
||||
ABEQ,
|
||||
ABGE,
|
||||
ABGT,
|
||||
ABL,
|
||||
ABLE,
|
||||
ABLT,
|
||||
ABNE,
|
||||
ABR,
|
||||
ABVC,
|
||||
ABVS,
|
||||
ACMP,
|
||||
ACMPU,
|
||||
ACNTLZW,
|
||||
ACNTLZWCC,
|
||||
ACRAND,
|
||||
ACRANDN,
|
||||
ACREQV,
|
||||
ACRNAND,
|
||||
ACRNOR,
|
||||
ACROR,
|
||||
ACRORN,
|
||||
ACRXOR,
|
||||
ADIVW,
|
||||
ADIVWCC,
|
||||
ADIVWVCC,
|
||||
ADIVWV,
|
||||
ADIVWU,
|
||||
ADIVWUCC,
|
||||
ADIVWUVCC,
|
||||
ADIVWUV,
|
||||
AEQV,
|
||||
AEQVCC,
|
||||
AEXTSB,
|
||||
AEXTSBCC,
|
||||
AEXTSH,
|
||||
AEXTSHCC,
|
||||
AFABS,
|
||||
AFABSCC,
|
||||
AFADD,
|
||||
AFADDCC,
|
||||
AFADDS,
|
||||
AFADDSCC,
|
||||
AFCMPO,
|
||||
AFCMPU,
|
||||
AFCTIW,
|
||||
AFCTIWCC,
|
||||
AFCTIWZ,
|
||||
AFCTIWZCC,
|
||||
AFDIV,
|
||||
AFDIVCC,
|
||||
AFDIVS,
|
||||
AFDIVSCC,
|
||||
AFMADD,
|
||||
AFMADDCC,
|
||||
AFMADDS,
|
||||
AFMADDSCC,
|
||||
AFMOVD,
|
||||
AFMOVDCC,
|
||||
AFMOVDU,
|
||||
AFMOVS,
|
||||
AFMOVSU,
|
||||
AFMSUB,
|
||||
AFMSUBCC,
|
||||
AFMSUBS,
|
||||
AFMSUBSCC,
|
||||
AFMUL,
|
||||
AFMULCC,
|
||||
AFMULS,
|
||||
AFMULSCC,
|
||||
AFNABS,
|
||||
AFNABSCC,
|
||||
AFNEG,
|
||||
AFNEGCC,
|
||||
AFNMADD,
|
||||
AFNMADDCC,
|
||||
AFNMADDS,
|
||||
AFNMADDSCC,
|
||||
AFNMSUB,
|
||||
AFNMSUBCC,
|
||||
AFNMSUBS,
|
||||
AFNMSUBSCC,
|
||||
AFRSP,
|
||||
AFRSPCC,
|
||||
AFSUB,
|
||||
AFSUBCC,
|
||||
AFSUBS,
|
||||
AFSUBSCC,
|
||||
AMOVMW,
|
||||
ALSW,
|
||||
ALWAR,
|
||||
AMOVWBR,
|
||||
AMOVB,
|
||||
AMOVBU,
|
||||
AMOVBZ,
|
||||
AMOVBZU,
|
||||
AMOVH,
|
||||
AMOVHBR,
|
||||
AMOVHU,
|
||||
AMOVHZ,
|
||||
AMOVHZU,
|
||||
AMOVW,
|
||||
AMOVWU,
|
||||
AMOVFL,
|
||||
AMOVCRFS,
|
||||
AMTFSB0,
|
||||
AMTFSB0CC,
|
||||
AMTFSB1,
|
||||
AMTFSB1CC,
|
||||
AMULHW,
|
||||
AMULHWCC,
|
||||
AMULHWU,
|
||||
AMULHWUCC,
|
||||
AMULLW,
|
||||
AMULLWCC,
|
||||
AMULLWVCC,
|
||||
AMULLWV,
|
||||
ANAND,
|
||||
ANANDCC,
|
||||
ANEG,
|
||||
ANEGCC,
|
||||
ANEGVCC,
|
||||
ANEGV,
|
||||
ANOR,
|
||||
ANORCC,
|
||||
AOR,
|
||||
AORCC,
|
||||
AORN,
|
||||
AORNCC,
|
||||
AREM,
|
||||
AREMCC,
|
||||
AREMV,
|
||||
AREMVCC,
|
||||
AREMU,
|
||||
AREMUCC,
|
||||
AREMUV,
|
||||
AREMUVCC,
|
||||
ARFI,
|
||||
ARLWMI,
|
||||
ARLWMICC,
|
||||
ARLWNM,
|
||||
ARLWNMCC,
|
||||
ASLW,
|
||||
ASLWCC,
|
||||
ASRW,
|
||||
ASRAW,
|
||||
ASRAWCC,
|
||||
ASRWCC,
|
||||
ASTSW,
|
||||
ASTWCCC,
|
||||
ASUB,
|
||||
ASUBCC,
|
||||
ASUBVCC,
|
||||
ASUBC,
|
||||
ASUBCCC,
|
||||
ASUBCV,
|
||||
ASUBCVCC,
|
||||
ASUBME,
|
||||
ASUBMECC,
|
||||
ASUBMEVCC,
|
||||
ASUBMEV,
|
||||
ASUBV,
|
||||
ASUBE,
|
||||
ASUBECC,
|
||||
ASUBEV,
|
||||
ASUBEVCC,
|
||||
ASUBZE,
|
||||
ASUBZECC,
|
||||
ASUBZEVCC,
|
||||
ASUBZEV,
|
||||
ASYNC,
|
||||
AXOR,
|
||||
AXORCC,
|
||||
|
||||
ADCBF,
|
||||
ADCBI,
|
||||
ADCBST,
|
||||
ADCBT,
|
||||
ADCBTST,
|
||||
ADCBZ,
|
||||
AECIWX,
|
||||
AECOWX,
|
||||
AEIEIO,
|
||||
AICBI,
|
||||
AISYNC,
|
||||
APTESYNC,
|
||||
ATLBIE,
|
||||
ATLBIEL,
|
||||
ATLBSYNC,
|
||||
ATW,
|
||||
|
||||
ASYSCALL,
|
||||
ADATA,
|
||||
AGLOBL,
|
||||
AGOK,
|
||||
AHISTORY,
|
||||
ANAME,
|
||||
ANOP,
|
||||
ARETURN,
|
||||
ATEXT,
|
||||
AWORD,
|
||||
AEND,
|
||||
ADYNT,
|
||||
AINIT,
|
||||
ASIGNAME,
|
||||
|
||||
ARFCI,
|
||||
|
||||
/* optional on 32-bit */
|
||||
AFRES,
|
||||
AFRESCC,
|
||||
AFRSQRTE,
|
||||
AFRSQRTECC,
|
||||
AFSEL,
|
||||
AFSELCC,
|
||||
AFSQRT,
|
||||
AFSQRTCC,
|
||||
AFSQRTS,
|
||||
AFSQRTSCC,
|
||||
|
||||
/* 64-bit */
|
||||
|
||||
ACNTLZD,
|
||||
ACNTLZDCC,
|
||||
ACMPW, /* CMP with L=0 */
|
||||
ACMPWU,
|
||||
ADIVD,
|
||||
ADIVDCC,
|
||||
ADIVDVCC,
|
||||
ADIVDV,
|
||||
ADIVDU,
|
||||
ADIVDUCC,
|
||||
ADIVDUVCC,
|
||||
ADIVDUV,
|
||||
AEXTSW,
|
||||
AEXTSWCC,
|
||||
/* AFCFIW; AFCFIWCC */
|
||||
AFCFID,
|
||||
AFCFIDCC,
|
||||
AFCTID,
|
||||
AFCTIDCC,
|
||||
AFCTIDZ,
|
||||
AFCTIDZCC,
|
||||
ALDAR,
|
||||
AMOVD,
|
||||
AMOVDU,
|
||||
AMOVWZ,
|
||||
AMOVWZU,
|
||||
AMULHD,
|
||||
AMULHDCC,
|
||||
AMULHDU,
|
||||
AMULHDUCC,
|
||||
AMULLD,
|
||||
AMULLDCC,
|
||||
AMULLDVCC,
|
||||
AMULLDV,
|
||||
ARFID,
|
||||
ARLDMI,
|
||||
ARLDMICC,
|
||||
ARLDC,
|
||||
ARLDCCC,
|
||||
ARLDCR,
|
||||
ARLDCRCC,
|
||||
ARLDCL,
|
||||
ARLDCLCC,
|
||||
ASLBIA,
|
||||
ASLBIE,
|
||||
ASLBMFEE,
|
||||
ASLBMFEV,
|
||||
ASLBMTE,
|
||||
ASLD,
|
||||
ASLDCC,
|
||||
ASRD,
|
||||
ASRAD,
|
||||
ASRADCC,
|
||||
ASRDCC,
|
||||
ASTDCCC,
|
||||
ATD,
|
||||
|
||||
/* 64-bit pseudo operation */
|
||||
ADWORD,
|
||||
AREMD,
|
||||
AREMDCC,
|
||||
AREMDV,
|
||||
AREMDVCC,
|
||||
AREMDU,
|
||||
AREMDUCC,
|
||||
AREMDUV,
|
||||
AREMDUVCC,
|
||||
|
||||
/* more 64-bit operations */
|
||||
AHRFID,
|
||||
|
||||
AUNDEF,
|
||||
AUSEFIELD,
|
||||
ATYPE,
|
||||
AFUNCDATA,
|
||||
APCDATA,
|
||||
ACHECKNIL,
|
||||
AVARDEF,
|
||||
AVARKILL,
|
||||
ADUFFCOPY,
|
||||
ADUFFZERO,
|
||||
|
||||
ALAST
|
||||
};
|
||||
|
||||
/* type/name */
|
||||
enum
|
||||
{
|
||||
D_GOK = 0,
|
||||
D_NONE,
|
||||
|
||||
/* name */
|
||||
D_EXTERN,
|
||||
D_STATIC,
|
||||
D_AUTO,
|
||||
D_PARAM,
|
||||
|
||||
/* type */
|
||||
D_BRANCH,
|
||||
D_OREG,
|
||||
D_CONST,
|
||||
D_FCONST,
|
||||
D_SCONST,
|
||||
D_REG,
|
||||
D_FPSCR,
|
||||
D_MSR,
|
||||
D_FREG,
|
||||
D_CREG,
|
||||
D_SPR,
|
||||
D_OPT, /* branch/trap option */
|
||||
D_FILE,
|
||||
D_FILE1,
|
||||
D_DCR, /* device control register */
|
||||
D_DCONST,
|
||||
D_ADDR, // not used, use D_CONST with non-empty sym.
|
||||
|
||||
D_LAST,
|
||||
|
||||
/* reg names for 9g OREGISTER */
|
||||
D_R0 = 0, // type is D_REG
|
||||
D_F0 = D_R0+NREG, // type is D_FREG
|
||||
|
||||
/* reg names in offset field iff type is D_SPR */
|
||||
D_XER = 1,
|
||||
D_LR = 8,
|
||||
D_CTR = 9
|
||||
/* and many supervisor level registers */
|
||||
};
|
||||
|
||||
/*
|
||||
* this is the ranlib header
|
||||
*/
|
||||
#define SYMDEF "__.GOSYMDEF"
|
||||
@@ -1,5 +0,0 @@
|
||||
# Copyright 2012 The Go Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
include ../../Make.dist
|
||||
338
src/cmd/9l/asm.c
338
src/cmd/9l/asm.c
@@ -1,338 +0,0 @@
|
||||
// Inferno utils/5l/asm.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/5l/asm.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
// Writing object files.
|
||||
|
||||
#include "l.h"
|
||||
#include "../ld/lib.h"
|
||||
#include "../ld/elf.h"
|
||||
#include "../ld/dwarf.h"
|
||||
|
||||
|
||||
char linuxdynld[] = "/lib64/ld64.so.1";
|
||||
char freebsddynld[] = "XXX";
|
||||
char openbsddynld[] = "XXX";
|
||||
char netbsddynld[] = "XXX";
|
||||
char dragonflydynld[] = "XXX";
|
||||
char solarisdynld[] = "XXX";
|
||||
|
||||
static int
|
||||
needlib(char *name)
|
||||
{
|
||||
char *p;
|
||||
LSym *s;
|
||||
|
||||
if(*name == '\0')
|
||||
return 0;
|
||||
|
||||
/* reuse hash code in symbol table */
|
||||
p = smprint(".dynlib.%s", name);
|
||||
s = linklookup(ctxt, p, 0);
|
||||
free(p);
|
||||
if(s->type == 0) {
|
||||
s->type = 100; // avoid SDATA, etc.
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nelfsym = 1;
|
||||
|
||||
// b is the addresses, a is the I-form branch instruction template, peform
|
||||
// addition so that the instruction jumps to address (offset) b.
|
||||
static int32
|
||||
braddoff(int32 a, int32 b)
|
||||
{
|
||||
return (((uint32)a) & 0xfc000003U) | (0x03fffffcU & (uint32)((a & 0x3fffffcU) + b));
|
||||
}
|
||||
|
||||
void
|
||||
adddynrela(LSym *rel, LSym *s, Reloc *r)
|
||||
{
|
||||
// TODO(minux)
|
||||
USED(rel); USED(s); USED(r);
|
||||
}
|
||||
|
||||
void
|
||||
adddynrel(LSym *s, Reloc *r)
|
||||
{
|
||||
LSym *targ;
|
||||
|
||||
// TODO(minux)
|
||||
|
||||
targ = r->sym;
|
||||
ctxt->cursym = s;
|
||||
diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ->name, r->type, targ->type);
|
||||
}
|
||||
|
||||
int
|
||||
elfreloc1(Reloc *r, vlong sectoff)
|
||||
{
|
||||
USED(r); USED(sectoff);
|
||||
// TODO(minux)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
elfsetupplt(void)
|
||||
{
|
||||
// TODO(minux)
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
machoreloc1(Reloc *r, vlong sectoff)
|
||||
{
|
||||
USED(r);
|
||||
USED(sectoff);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
archreloc(Reloc *r, LSym *s, vlong *val)
|
||||
{
|
||||
uint32 o1, o2;
|
||||
int32 t;
|
||||
|
||||
if(linkmode == LinkExternal) {
|
||||
// TODO(minux): translate R_ADDRPOWER and R_CALLPOWER into standard ELF relocations.
|
||||
// R_ADDRPOWER corresponds to R_PPC_ADDR16_HA and R_PPC_ADDR16_LO.
|
||||
// R_CALLPOWER corresponds to R_PPC_REL24.
|
||||
return -1;
|
||||
}
|
||||
switch(r->type) {
|
||||
case R_CONST:
|
||||
*val = r->add;
|
||||
return 0;
|
||||
case R_GOTOFF:
|
||||
*val = symaddr(r->sym) + r->add - symaddr(linklookup(ctxt, ".got", 0));
|
||||
return 0;
|
||||
case R_ADDRPOWER:
|
||||
// r->add is two power64 instructions holding an immediate 32-bit constant.
|
||||
// We want to add r->sym's address to that constant.
|
||||
// The encoding of the immediate x<<16 + y,
|
||||
// where x is the low 16 bits of the first instruction and y is the low 16
|
||||
// bits of the second. Both x and y are signed (int16, not uint16).
|
||||
o1 = r->add >> 32;
|
||||
o2 = r->add;
|
||||
t = symaddr(r->sym);
|
||||
if(t < 0) {
|
||||
ctxt->diag("relocation for %s is too big (>=2G): %lld", s->name, symaddr(r->sym));
|
||||
}
|
||||
t += ((o1 & 0xffff) << 16) + ((int32)o2 << 16 >> 16);
|
||||
if(t & 0x8000)
|
||||
t += 0x10000;
|
||||
o1 = (o1 & 0xffff0000) | ((t >> 16) & 0xffff);
|
||||
o2 = (o2 & 0xffff0000) | (t & 0xffff);
|
||||
// when laid out, the instruction order must always be o1, o2.
|
||||
if(ctxt->arch->endian == BigEndian)
|
||||
*val = ((vlong)o1 << 32) | o2;
|
||||
else
|
||||
*val = ((vlong)o2 << 32) | o1;
|
||||
return 0;
|
||||
case R_CALLPOWER:
|
||||
*val = braddoff((uint32)r->add, (int32)(symaddr(r->sym) - (s->value + r->off)));
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
adddynsym(Link *ctxt, LSym *s)
|
||||
{
|
||||
USED(ctxt); USED(s);
|
||||
// TODO(minux)
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
adddynlib(char *lib)
|
||||
{
|
||||
LSym *s;
|
||||
|
||||
if(!needlib(lib))
|
||||
return;
|
||||
|
||||
if(iself) {
|
||||
s = linklookup(ctxt, ".dynstr", 0);
|
||||
if(s->size == 0)
|
||||
addstring(s, "");
|
||||
elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED, addstring(s, lib));
|
||||
} else {
|
||||
diag("adddynlib: unsupported binary format");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
asmb(void)
|
||||
{
|
||||
uint32 symo;
|
||||
Section *sect;
|
||||
LSym *sym;
|
||||
int i;
|
||||
|
||||
if(debug['v'])
|
||||
Bprint(&bso, "%5.2f asmb\n", cputime());
|
||||
Bflush(&bso);
|
||||
|
||||
if(iself)
|
||||
asmbelfsetup();
|
||||
|
||||
sect = segtext.sect;
|
||||
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
||||
codeblk(sect->vaddr, sect->len);
|
||||
for(sect = sect->next; sect != nil; sect = sect->next) {
|
||||
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
||||
datblk(sect->vaddr, sect->len);
|
||||
}
|
||||
|
||||
if(segrodata.filelen > 0) {
|
||||
if(debug['v'])
|
||||
Bprint(&bso, "%5.2f rodatblk\n", cputime());
|
||||
Bflush(&bso);
|
||||
|
||||
cseek(segrodata.fileoff);
|
||||
datblk(segrodata.vaddr, segrodata.filelen);
|
||||
}
|
||||
|
||||
if(debug['v'])
|
||||
Bprint(&bso, "%5.2f datblk\n", cputime());
|
||||
Bflush(&bso);
|
||||
|
||||
cseek(segdata.fileoff);
|
||||
datblk(segdata.vaddr, segdata.filelen);
|
||||
|
||||
/* output symbol table */
|
||||
symsize = 0;
|
||||
lcsize = 0;
|
||||
symo = 0;
|
||||
if(!debug['s']) {
|
||||
// TODO: rationalize
|
||||
if(debug['v'])
|
||||
Bprint(&bso, "%5.2f sym\n", cputime());
|
||||
Bflush(&bso);
|
||||
switch(HEADTYPE) {
|
||||
default:
|
||||
if(iself)
|
||||
goto ElfSym;
|
||||
case Hplan9:
|
||||
symo = segdata.fileoff+segdata.filelen;
|
||||
break;
|
||||
ElfSym:
|
||||
symo = segdata.fileoff+segdata.filelen;
|
||||
symo = rnd(symo, INITRND);
|
||||
break;
|
||||
}
|
||||
cseek(symo);
|
||||
switch(HEADTYPE) {
|
||||
default:
|
||||
if(iself) {
|
||||
if(debug['v'])
|
||||
Bprint(&bso, "%5.2f elfsym\n", cputime());
|
||||
asmelfsym();
|
||||
cflush();
|
||||
cwrite(elfstrdat, elfstrsize);
|
||||
|
||||
if(debug['v'])
|
||||
Bprint(&bso, "%5.2f dwarf\n", cputime());
|
||||
dwarfemitdebugsections();
|
||||
|
||||
if(linkmode == LinkExternal)
|
||||
elfemitreloc();
|
||||
}
|
||||
break;
|
||||
case Hplan9:
|
||||
asmplan9sym();
|
||||
cflush();
|
||||
|
||||
sym = linklookup(ctxt, "pclntab", 0);
|
||||
if(sym != nil) {
|
||||
lcsize = sym->np;
|
||||
for(i=0; i < lcsize; i++)
|
||||
cput(sym->p[i]);
|
||||
|
||||
cflush();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ctxt->cursym = nil;
|
||||
if(debug['v'])
|
||||
Bprint(&bso, "%5.2f header\n", cputime());
|
||||
Bflush(&bso);
|
||||
cseek(0L);
|
||||
switch(HEADTYPE) {
|
||||
default:
|
||||
case Hplan9: /* plan 9 */
|
||||
LPUT(0x647); /* magic */
|
||||
LPUT(segtext.filelen); /* sizes */
|
||||
LPUT(segdata.filelen);
|
||||
LPUT(segdata.len - segdata.filelen);
|
||||
LPUT(symsize); /* nsyms */
|
||||
LPUT(entryvalue()); /* va of entry */
|
||||
LPUT(0L);
|
||||
LPUT(lcsize);
|
||||
break;
|
||||
case Hlinux:
|
||||
case Hfreebsd:
|
||||
case Hnetbsd:
|
||||
case Hopenbsd:
|
||||
case Hnacl:
|
||||
asmbelf(symo);
|
||||
break;
|
||||
}
|
||||
cflush();
|
||||
if(debug['c']){
|
||||
print("textsize=%ulld\n", segtext.filelen);
|
||||
print("datsize=%ulld\n", segdata.filelen);
|
||||
print("bsssize=%ulld\n", segdata.len - segdata.filelen);
|
||||
print("symsize=%d\n", symsize);
|
||||
print("lcsize=%d\n", lcsize);
|
||||
print("total=%lld\n", segtext.filelen+segdata.len+symsize+lcsize);
|
||||
}
|
||||
}
|
||||
|
||||
vlong
|
||||
rnd(vlong v, int32 r)
|
||||
{
|
||||
vlong c;
|
||||
|
||||
if(r <= 0)
|
||||
return v;
|
||||
v += r - 1;
|
||||
c = v % r;
|
||||
if(c < 0)
|
||||
c += r;
|
||||
v -= c;
|
||||
return v;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build ignore
|
||||
|
||||
/*
|
||||
|
||||
9l is the linker for the Power64.
|
||||
The $GOARCH for these tools is power64 (big endian) or
|
||||
power64le (little endian).
|
||||
|
||||
The flags are documented in ../ld/doc.go.
|
||||
|
||||
*/
|
||||
package main
|
||||
100
src/cmd/9l/l.h
100
src/cmd/9l/l.h
@@ -1,100 +0,0 @@
|
||||
// cmd/9l/l.h from Vita Nuova.
|
||||
//
|
||||
// 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-2008 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-2008 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 <libc.h>
|
||||
#include <bio.h>
|
||||
#include <link.h>
|
||||
#include "9.out.h"
|
||||
|
||||
#ifndef EXTERN
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
thechar = '9',
|
||||
PtrSize = 8,
|
||||
IntSize = 8,
|
||||
RegSize = 8,
|
||||
MaxAlign = 32, // max data alignment
|
||||
FuncAlign = 8
|
||||
};
|
||||
|
||||
#define P ((Prog*)0)
|
||||
#define S ((LSym*)0)
|
||||
|
||||
enum
|
||||
{
|
||||
FPCHIP = 1,
|
||||
STRINGSZ = 200,
|
||||
MAXHIST = 20, /* limit of path elements for history symbols */
|
||||
DATBLK = 1024,
|
||||
NHASH = 10007,
|
||||
NHUNK = 100000,
|
||||
MINSIZ = 64,
|
||||
NENT = 100,
|
||||
NSCHED = 20,
|
||||
MINLC = 4,
|
||||
|
||||
Roffset = 22, /* no. bits for offset in relocation address */
|
||||
Rindex = 10 /* no. bits for index in relocation address */
|
||||
};
|
||||
|
||||
EXTERN int32 autosize;
|
||||
EXTERN LSym* datap;
|
||||
EXTERN int debug[128];
|
||||
EXTERN int32 lcsize;
|
||||
EXTERN char literal[32];
|
||||
EXTERN int nerrors;
|
||||
EXTERN vlong instoffset;
|
||||
EXTERN char* rpath;
|
||||
EXTERN vlong pc;
|
||||
EXTERN int32 symsize;
|
||||
EXTERN int32 staticgen;
|
||||
EXTERN Prog* lastp;
|
||||
EXTERN vlong textsize;
|
||||
|
||||
void asmb(void);
|
||||
void adddynlib(char *lib);
|
||||
void adddynrel(LSym *s, Reloc *r);
|
||||
void adddynsym(Link *ctxt, LSym *s);
|
||||
int archreloc(Reloc *r, LSym *s, vlong *val);
|
||||
void listinit(void);
|
||||
vlong rnd(vlong, int32);
|
||||
|
||||
#define LPUT(a) (ctxt->arch->endian == BigEndian ? lputb(a):lputl(a))
|
||||
#define WPUT(a) (ctxt->arch->endian == BigEndian ? wputb(a):wputl(a))
|
||||
#define VPUT(a) (ctxt->arch->endian == BigEndian ? vputb(a):vputl(a))
|
||||
|
||||
/* Used by ../ld/dwarf.c */
|
||||
enum
|
||||
{
|
||||
DWARFREGSP = 1
|
||||
};
|
||||
@@ -1,40 +0,0 @@
|
||||
// Inferno utils/5l/list.h
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/5l/list.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.
|
||||
|
||||
// Printing.
|
||||
|
||||
#include "l.h"
|
||||
#include "../ld/lib.h"
|
||||
|
||||
void
|
||||
listinit(void)
|
||||
{
|
||||
listinit9();
|
||||
}
|
||||
108
src/cmd/9l/obj.c
108
src/cmd/9l/obj.c
@@ -1,108 +0,0 @@
|
||||
// Inferno utils/5l/obj.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/5l/obj.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.
|
||||
|
||||
// Reading object files.
|
||||
|
||||
#include "l.h"
|
||||
#include "../ld/lib.h"
|
||||
#include "../ld/elf.h"
|
||||
#include "../ld/dwarf.h"
|
||||
#include <ar.h>
|
||||
|
||||
char *thestring = "power64";
|
||||
LinkArch *thelinkarch;
|
||||
|
||||
void
|
||||
linkarchinit(void)
|
||||
{
|
||||
thestring = getgoarch();
|
||||
if(strcmp(thestring, "power64le") == 0)
|
||||
thelinkarch = &linkpower64le;
|
||||
else
|
||||
thelinkarch = &linkpower64;
|
||||
}
|
||||
|
||||
void
|
||||
archinit(void)
|
||||
{
|
||||
// getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
|
||||
// Go was built; see ../../make.bash.
|
||||
if(linkmode == LinkAuto && strcmp(getgoextlinkenabled(), "0") == 0)
|
||||
linkmode = LinkInternal;
|
||||
|
||||
switch(HEADTYPE) {
|
||||
default:
|
||||
if(linkmode == LinkAuto)
|
||||
linkmode = LinkInternal;
|
||||
if(linkmode == LinkExternal && strcmp(getgoextlinkenabled(), "1") != 0)
|
||||
sysfatal("cannot use -linkmode=external with -H %s", headstr(HEADTYPE));
|
||||
break;
|
||||
}
|
||||
|
||||
switch(HEADTYPE) {
|
||||
default:
|
||||
diag("unknown -H option");
|
||||
errorexit();
|
||||
case Hplan9: /* plan 9 */
|
||||
HEADR = 32L;
|
||||
if(INITTEXT == -1)
|
||||
INITTEXT = 4128;
|
||||
if(INITDAT == -1)
|
||||
INITDAT = 0;
|
||||
if(INITRND == -1)
|
||||
INITRND = 4096;
|
||||
break;
|
||||
case Hlinux: /* power64 elf */
|
||||
debug['d'] = 1; // TODO(minux): dynamic linking is not supported yet.
|
||||
elfinit();
|
||||
HEADR = ELFRESERVE;
|
||||
if(INITTEXT == -1)
|
||||
INITTEXT = 0x10000 + HEADR;
|
||||
if(INITDAT == -1)
|
||||
INITDAT = 0;
|
||||
if(INITRND == -1)
|
||||
INITRND = 0x10000;
|
||||
break;
|
||||
case Hnacl:
|
||||
elfinit();
|
||||
HEADR = 0x10000;
|
||||
funcalign = 16;
|
||||
if(INITTEXT == -1)
|
||||
INITTEXT = 0x20000;
|
||||
if(INITDAT == -1)
|
||||
INITDAT = 0;
|
||||
if(INITRND == -1)
|
||||
INITRND = 0x10000;
|
||||
break;
|
||||
}
|
||||
if(INITDAT != 0 && INITRND != 0)
|
||||
print("warning: -D0x%ux is ignored because of -R0x%ux\n",
|
||||
INITDAT, INITRND);
|
||||
}
|
||||
@@ -283,7 +283,7 @@ func compareAPI(w io.Writer, features, required, optional, exception []string) (
|
||||
delete(optionalSet, newFeature)
|
||||
} else {
|
||||
fmt.Fprintf(w, "+%s\n", newFeature)
|
||||
if !*allowNew {
|
||||
if !*allowNew || !strings.Contains(runtime.Version(), "devel") {
|
||||
ok = false // we're in lock-down mode for next release
|
||||
}
|
||||
}
|
||||
@@ -313,11 +313,15 @@ func fileFeatures(filename string) []string {
|
||||
if err != nil {
|
||||
log.Fatalf("Error reading file %s: %v", filename, err)
|
||||
}
|
||||
text := strings.TrimSpace(string(bs))
|
||||
if text == "" {
|
||||
return nil
|
||||
lines := strings.Split(string(bs), "\n")
|
||||
var nonblank []string
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
if line != "" && !strings.HasPrefix(line, "#") {
|
||||
nonblank = append(nonblank, line)
|
||||
}
|
||||
}
|
||||
return strings.Split(text, "\n")
|
||||
return nonblank
|
||||
}
|
||||
|
||||
var fset = token.NewFileSet()
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -53,7 +54,7 @@ func main() {
|
||||
}
|
||||
|
||||
out, err = exec.Command("go", "tool", "api",
|
||||
"-c", file("go1", "go1.1", "go1.2", "go1.3"),
|
||||
"-c", file("go1", "go1.1", "go1.2", "go1.3", "go1.4"),
|
||||
"-next", file("next"),
|
||||
"-except", file("except")).CombinedOutput()
|
||||
if err != nil {
|
||||
@@ -105,7 +106,7 @@ func prepGoPath() string {
|
||||
}
|
||||
|
||||
// The GOPATH we'll return
|
||||
gopath := filepath.Join(os.TempDir(), "gopath-api-"+cleanUsername(username), goToolsVersion)
|
||||
gopath := filepath.Join(os.TempDir(), "gopath-api-"+cleanUsername(username)+"-"+cleanUsername(strings.Fields(runtime.Version())[0]), goToolsVersion)
|
||||
|
||||
// cloneDir is where we run "hg clone".
|
||||
cloneDir := filepath.Join(gopath, "src", "code.google.com", "p")
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user