mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/5l etc: restore comments lost during C -> Go conversion
It appears that c2go dropped comments inside struct { ... } and enum { ... }.
Restore them.
Identified missing comments by checking for comments present
in the C code but not the Go code, made a list, and then reapplied
with some mechanical help.
Missing comment finder: http://play.golang.org/p/g6qNUAo1Y0
Change-Id: I323ab45c7ef9d51e28eab3b699eb14bee1eef66b
Reviewed-on: https://go-review.googlesource.com/6899
Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
parent
d970bea885
commit
cdb7d7dcc2
36 changed files with 1271 additions and 931 deletions
|
|
@ -619,7 +619,7 @@ func asmb() {
|
||||||
fmt.Fprintf(&ld.Bso, "%5.2f dwarf\n", obj.Cputime())
|
fmt.Fprintf(&ld.Bso, "%5.2f dwarf\n", obj.Cputime())
|
||||||
}
|
}
|
||||||
|
|
||||||
if ld.Debug['w'] == 0 {
|
if ld.Debug['w'] == 0 { // TODO(minux): enable DWARF Support
|
||||||
dwarfoff := uint32(ld.Rnd(int64(uint64(ld.HEADR)+ld.Segtext.Length), int64(ld.INITRND)) + ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND)))
|
dwarfoff := uint32(ld.Rnd(int64(uint64(ld.HEADR)+ld.Segtext.Length), int64(ld.INITRND)) + ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND)))
|
||||||
ld.Cseek(int64(dwarfoff))
|
ld.Cseek(int64(dwarfoff))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,8 +67,8 @@ const (
|
||||||
PtrSize = 4
|
PtrSize = 4
|
||||||
IntSize = 4
|
IntSize = 4
|
||||||
RegSize = 4
|
RegSize = 4
|
||||||
MaxAlign = 8
|
MaxAlign = 8 // max data alignment
|
||||||
FuncAlign = 4
|
FuncAlign = 4 // single-instruction alignment
|
||||||
MINLC = 4
|
MINLC = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -134,11 +134,11 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
|
||||||
r.Type = ld.R_ADDR
|
r.Type = ld.R_ADDR
|
||||||
return
|
return
|
||||||
|
|
||||||
// TODO: What is the difference between all these?
|
|
||||||
// Handle relocations found in Mach-O object files.
|
// Handle relocations found in Mach-O object files.
|
||||||
case 512 + ld.MACHO_X86_64_RELOC_UNSIGNED*2 + 0,
|
case 512 + ld.MACHO_X86_64_RELOC_UNSIGNED*2 + 0,
|
||||||
512 + ld.MACHO_X86_64_RELOC_SIGNED*2 + 0,
|
512 + ld.MACHO_X86_64_RELOC_SIGNED*2 + 0,
|
||||||
512 + ld.MACHO_X86_64_RELOC_BRANCH*2 + 0:
|
512 + ld.MACHO_X86_64_RELOC_BRANCH*2 + 0:
|
||||||
|
// TODO: What is the difference between all these?
|
||||||
r.Type = ld.R_ADDR
|
r.Type = ld.R_ADDR
|
||||||
|
|
||||||
if targ.Type == ld.SDYNIMPORT {
|
if targ.Type == ld.SDYNIMPORT {
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,3 @@
|
||||||
// Inferno utils/6l/asm.c
|
|
||||||
// http://code.google.com/p/inferno-os/source/browse/utils/6l/asm.c
|
|
||||||
//
|
|
||||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
|
||||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
|
||||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
|
||||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
|
||||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
|
||||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
|
||||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
|
||||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
// THE SOFTWARE.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
// Writing object files.
|
|
||||||
|
|
||||||
// Inferno utils/6l/l.h
|
// Inferno utils/6l/l.h
|
||||||
// http://code.google.com/p/inferno-os/source/browse/utils/6l/l.h
|
// http://code.google.com/p/inferno-os/source/browse/utils/6l/l.h
|
||||||
//
|
//
|
||||||
|
|
@ -62,9 +28,11 @@ package main
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
const (
|
const (
|
||||||
thechar = '6'
|
thechar = '6'
|
||||||
MaxAlign = 32
|
MaxAlign = 32 // max data alignment
|
||||||
FuncAlign = 16
|
FuncAlign = 16
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import "cmd/internal/obj/x86"
|
||||||
import "cmd/internal/gc"
|
import "cmd/internal/gc"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
NREGVAR = 16
|
NREGVAR = 16 /* 8 integer + 8 floating */
|
||||||
)
|
)
|
||||||
|
|
||||||
var regname = []string{
|
var regname = []string{
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,3 @@
|
||||||
// Inferno utils/8l/asm.c
|
|
||||||
// http://code.google.com/p/inferno-os/source/browse/utils/8l/asm.c
|
|
||||||
//
|
|
||||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
|
||||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
|
||||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
|
||||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
|
||||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
|
||||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
|
||||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
|
||||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
|
||||||
// in the Software without restriction, including without limitation the rights
|
|
||||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
// copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
// THE SOFTWARE.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
// Writing object files.
|
|
||||||
|
|
||||||
// Inferno utils/8l/l.h
|
// Inferno utils/8l/l.h
|
||||||
// http://code.google.com/p/inferno-os/source/browse/utils/8l/l.h
|
// http://code.google.com/p/inferno-os/source/browse/utils/8l/l.h
|
||||||
//
|
//
|
||||||
|
|
@ -62,12 +28,14 @@ package main
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
const (
|
const (
|
||||||
thechar = '8'
|
thechar = '8'
|
||||||
PtrSize = 4
|
PtrSize = 4
|
||||||
IntSize = 4
|
IntSize = 4
|
||||||
RegSize = 4
|
RegSize = 4
|
||||||
MaxAlign = 32
|
MaxAlign = 32 // max data alignment
|
||||||
FuncAlign = 16
|
FuncAlign = 16
|
||||||
MINLC = 1
|
MINLC = 1
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,12 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
// Copyright 2014 The Go Authors. All rights reserved.
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
// Many Power ISA arithmetic and logical instructions come in four
|
// Many Power ISA arithmetic and logical instructions come in four
|
||||||
// standard variants. These bits let us map between variants.
|
// standard variants. These bits let us map between variants.
|
||||||
const (
|
const (
|
||||||
V_CC = 1 << 0
|
V_CC = 1 << 0 // xCC (affect CR field 0 flags)
|
||||||
V_V = 1 << 1
|
V_V = 1 << 1 // xV (affect SO and OV flags)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import "cmd/internal/obj/ppc64"
|
||||||
import "cmd/internal/gc"
|
import "cmd/internal/gc"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
NREGVAR = 64
|
NREGVAR = 64 /* 32 general + 32 floating */
|
||||||
)
|
)
|
||||||
|
|
||||||
var regname = []string{
|
var regname = []string{
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ const (
|
||||||
PtrSize = 8
|
PtrSize = 8
|
||||||
IntSize = 8
|
IntSize = 8
|
||||||
RegSize = 8
|
RegSize = 8
|
||||||
MaxAlign = 32
|
MaxAlign = 32 // max data alignment
|
||||||
FuncAlign = 8
|
FuncAlign = 8
|
||||||
MINLC = 4
|
MINLC = 4
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -206,15 +206,27 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type EscState struct {
|
type EscState struct {
|
||||||
|
// Fake node that all
|
||||||
|
// - return values and output variables
|
||||||
|
// - parameters on imported functions not marked 'safe'
|
||||||
|
// - assignments to global variables
|
||||||
|
// flow to.
|
||||||
theSink Node
|
theSink Node
|
||||||
|
|
||||||
|
// If an analyzed function is recorded to return
|
||||||
|
// pieces obtained via indirection from a parameter,
|
||||||
|
// and later there is a call f(x) to that function,
|
||||||
|
// we create a link funcParam <- x to record that fact.
|
||||||
|
// The funcParam node is handled specially in escflood.
|
||||||
funcParam Node
|
funcParam Node
|
||||||
dsts *NodeList
|
|
||||||
loopdepth int
|
dsts *NodeList // all dst nodes
|
||||||
pdepth int
|
loopdepth int // for detecting nested loop scopes
|
||||||
dstcount int
|
pdepth int // for debug printing in recursions.
|
||||||
edgecount int
|
dstcount int // diagnostic
|
||||||
noesc *NodeList
|
edgecount int // diagnostic
|
||||||
recursive bool
|
noesc *NodeList // list of possible non-escaping nodes, for printing
|
||||||
|
recursive bool // recursive function or group of mutually recursive functions.
|
||||||
}
|
}
|
||||||
|
|
||||||
var tags [16]*string
|
var tags [16]*string
|
||||||
|
|
@ -530,7 +542,10 @@ func esc(e *EscState, n *Node, up *Node) {
|
||||||
// However, without this special case b will escape, because we assign to OIND/ODOTPTR.
|
// However, without this special case b will escape, because we assign to OIND/ODOTPTR.
|
||||||
case OAS,
|
case OAS,
|
||||||
OASOP:
|
OASOP:
|
||||||
if (n.Left.Op == OIND || n.Left.Op == ODOTPTR) && n.Left.Left.Op == ONAME && (n.Right.Op == OSLICE || n.Right.Op == OSLICE3 || n.Right.Op == OSLICESTR) && (n.Right.Left.Op == OIND || n.Right.Left.Op == ODOTPTR) && n.Right.Left.Left.Op == ONAME && n.Left.Left == n.Right.Left.Left { // dst is ONAME dereference // src is slice operation // slice is applied to ONAME dereference // dst and src reference the same base ONAME
|
if (n.Left.Op == OIND || n.Left.Op == ODOTPTR) && n.Left.Left.Op == ONAME && // dst is ONAME dereference
|
||||||
|
(n.Right.Op == OSLICE || n.Right.Op == OSLICE3 || n.Right.Op == OSLICESTR) && // src is slice operation
|
||||||
|
(n.Right.Left.Op == OIND || n.Right.Left.Op == ODOTPTR) && n.Right.Left.Left.Op == ONAME && // slice is applied to ONAME dereference
|
||||||
|
n.Left.Left == n.Right.Left.Left { // dst and src reference the same base ONAME
|
||||||
|
|
||||||
// Here we also assume that the statement will not contain calls,
|
// Here we also assume that the statement will not contain calls,
|
||||||
// that is, that order will move any calls to init.
|
// that is, that order will move any calls to init.
|
||||||
|
|
@ -578,13 +593,12 @@ func esc(e *EscState, n *Node, up *Node) {
|
||||||
if e.loopdepth == 1 { // top level
|
if e.loopdepth == 1 { // top level
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
fallthrough
|
|
||||||
|
|
||||||
// go f(x) - f and x escape
|
|
||||||
// arguments leak out of scope
|
// arguments leak out of scope
|
||||||
// TODO: leak to a dummy node instead
|
// TODO: leak to a dummy node instead
|
||||||
// fallthrough
|
fallthrough
|
||||||
|
|
||||||
case OPROC:
|
case OPROC:
|
||||||
|
// go f(x) - f and x escape
|
||||||
escassign(e, &e.theSink, n.Left.Left)
|
escassign(e, &e.theSink, n.Left.Left)
|
||||||
|
|
||||||
escassign(e, &e.theSink, n.Left.Right) // ODDDARG for call
|
escassign(e, &e.theSink, n.Left.Right) // ODDDARG for call
|
||||||
|
|
@ -899,14 +913,15 @@ func escassign(e *EscState, dst *Node, src *Node) {
|
||||||
OSLICEARR,
|
OSLICEARR,
|
||||||
OSLICE3ARR,
|
OSLICE3ARR,
|
||||||
OSLICESTR:
|
OSLICESTR:
|
||||||
|
// Conversions, field access, slice all preserve the input value.
|
||||||
escassign(e, dst, src.Left)
|
escassign(e, dst, src.Left)
|
||||||
|
|
||||||
// Append returns first argument.
|
|
||||||
case OAPPEND:
|
case OAPPEND:
|
||||||
|
// Append returns first argument.
|
||||||
escassign(e, dst, src.List.N)
|
escassign(e, dst, src.List.N)
|
||||||
|
|
||||||
// Index of array preserves input value.
|
|
||||||
case OINDEX:
|
case OINDEX:
|
||||||
|
// Index of array preserves input value.
|
||||||
if Isfixedarray(src.Left.Type) {
|
if Isfixedarray(src.Left.Type) {
|
||||||
escassign(e, dst, src.Left)
|
escassign(e, dst, src.Left)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// These values are known by runtime.
|
||||||
|
// The MEMx and NOEQx values must run in parallel. See algtype.
|
||||||
AMEM = iota
|
AMEM = iota
|
||||||
AMEM0
|
AMEM0
|
||||||
AMEM8
|
AMEM8
|
||||||
|
|
@ -58,9 +60,9 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Mpscale = 29
|
Mpscale = 29 // safely smaller than bits in a long
|
||||||
Mpprec = 16
|
Mpprec = 16 // Mpscale*Mpprec is max number of bits
|
||||||
Mpnorm = Mpprec - 1
|
Mpnorm = Mpprec - 1 // significant words in a normalized float
|
||||||
Mpbase = 1 << Mpscale
|
Mpbase = 1 << Mpscale
|
||||||
Mpsign = Mpbase >> 1
|
Mpsign = Mpbase >> 1
|
||||||
Mpmask = Mpbase - 1
|
Mpmask = Mpbase - 1
|
||||||
|
|
@ -86,42 +88,44 @@ type Mpcplx struct {
|
||||||
type Val struct {
|
type Val struct {
|
||||||
Ctype int16
|
Ctype int16
|
||||||
U struct {
|
U struct {
|
||||||
Reg int16
|
Reg int16 // OREGISTER
|
||||||
Bval int16
|
Bval int16 // bool value CTBOOL
|
||||||
Xval *Mpint
|
Xval *Mpint // int CTINT, rune CTRUNE
|
||||||
Fval *Mpflt
|
Fval *Mpflt // float CTFLT
|
||||||
Cval *Mpcplx
|
Cval *Mpcplx // float CTCPLX
|
||||||
Sval string
|
Sval string // string CTSTR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Pkg struct {
|
type Pkg struct {
|
||||||
Name string
|
Name string // package name
|
||||||
Path string
|
Path string // string literal used in import statement
|
||||||
Pathsym *Sym
|
Pathsym *Sym
|
||||||
Prefix string
|
Prefix string // escaped path for use in symbol table
|
||||||
Imported uint8
|
Imported uint8 // export data of this package was parsed
|
||||||
Exported int8
|
Exported int8 // import line written in export data
|
||||||
Direct int8
|
Direct int8 // imported directly
|
||||||
Safe bool
|
Safe bool // whether the package is marked as safe
|
||||||
Syms map[string]*Sym
|
Syms map[string]*Sym
|
||||||
}
|
}
|
||||||
|
|
||||||
type Sym struct {
|
type Sym struct {
|
||||||
Lexical uint16
|
Lexical uint16
|
||||||
Flags uint8
|
Flags uint8
|
||||||
Sym uint8
|
Sym uint8 // huffman encoding in object file
|
||||||
Link *Sym
|
Link *Sym
|
||||||
Uniqgen uint32
|
Uniqgen uint32
|
||||||
Importdef *Pkg
|
Importdef *Pkg // where imported definition was found
|
||||||
Linkname string
|
Linkname string // link name
|
||||||
|
|
||||||
|
// saved and restored by dcopy
|
||||||
Pkg *Pkg
|
Pkg *Pkg
|
||||||
Name string
|
Name string // variable name
|
||||||
Def *Node
|
Def *Node // definition: ONAME OTYPE OPACK or OLITERAL
|
||||||
Label *Label
|
Label *Label // corresponding label (ephemeral)
|
||||||
Block int32
|
Block int32 // blocknumber to catch redeclaration
|
||||||
Lastlineno int32
|
Lastlineno int32 // last declaration for diagnostic
|
||||||
Origpkg *Pkg
|
Origpkg *Pkg // original package for . import
|
||||||
Lsym *obj.LSym
|
Lsym *obj.LSym
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,45 +134,63 @@ type Type struct {
|
||||||
Nointerface bool
|
Nointerface bool
|
||||||
Noalg uint8
|
Noalg uint8
|
||||||
Chan uint8
|
Chan uint8
|
||||||
Trecur uint8
|
Trecur uint8 // to detect loops
|
||||||
Printed uint8
|
Printed uint8
|
||||||
Embedded uint8
|
Embedded uint8 // TFIELD embedded type
|
||||||
Siggen uint8
|
Siggen uint8
|
||||||
Funarg uint8
|
Funarg uint8 // on TSTRUCT and TFIELD
|
||||||
Copyany uint8
|
Copyany uint8
|
||||||
Local uint8
|
Local uint8 // created in this file
|
||||||
Deferwidth uint8
|
Deferwidth uint8
|
||||||
Broke uint8
|
Broke uint8 // broken type definition.
|
||||||
Isddd uint8
|
Isddd uint8 // TFIELD is ... argument
|
||||||
Align uint8
|
Align uint8
|
||||||
Haspointers uint8
|
Haspointers uint8 // 0 unknown, 1 no, 2 yes
|
||||||
Nod *Node
|
|
||||||
Orig *Type
|
Nod *Node // canonical OTYPE node
|
||||||
|
Orig *Type // original type (type literal or predefined type)
|
||||||
Lineno int
|
Lineno int
|
||||||
|
|
||||||
|
// TFUNC
|
||||||
Thistuple int
|
Thistuple int
|
||||||
Outtuple int
|
Outtuple int
|
||||||
Intuple int
|
Intuple int
|
||||||
Outnamed uint8
|
Outnamed uint8
|
||||||
|
|
||||||
Method *Type
|
Method *Type
|
||||||
Xmethod *Type
|
Xmethod *Type
|
||||||
|
|
||||||
Sym *Sym
|
Sym *Sym
|
||||||
Vargen int32
|
Vargen int32 // unique name for OTYPE/ONAME
|
||||||
|
|
||||||
Nname *Node
|
Nname *Node
|
||||||
Argwid int64
|
Argwid int64
|
||||||
Type *Type
|
|
||||||
Width int64
|
// most nodes
|
||||||
Down *Type
|
Type *Type // actual type for TFIELD, element type for TARRAY, TCHAN, TMAP, TPTRxx
|
||||||
Outer *Type
|
Width int64 // offset in TFIELD, width in all others
|
||||||
Note *string
|
|
||||||
Bound int64
|
// TFIELD
|
||||||
Bucket *Type
|
Down *Type // next struct field, also key type in TMAP
|
||||||
Hmap *Type
|
Outer *Type // outer struct
|
||||||
Hiter *Type
|
Note *string // literal string annotation
|
||||||
Map *Type
|
|
||||||
Maplineno int32
|
// TARRAY
|
||||||
Embedlineno int32
|
Bound int64 // negative is dynamic array
|
||||||
|
|
||||||
|
// TMAP
|
||||||
|
Bucket *Type // internal type representing a hash bucket
|
||||||
|
Hmap *Type // internal type representing a Hmap (map header object)
|
||||||
|
Hiter *Type // internal type representing hash iterator state
|
||||||
|
Map *Type // link from the above 3 internal types back to the map type.
|
||||||
|
|
||||||
|
Maplineno int32 // first use of TFORW as map key
|
||||||
|
Embedlineno int32 // first use of TFORW as embedded type
|
||||||
|
|
||||||
|
// for TFORW, where to copy the eventual value to
|
||||||
Copyto *NodeList
|
Copyto *NodeList
|
||||||
Lastfn *Node
|
|
||||||
|
Lastfn *Node // for usefield
|
||||||
}
|
}
|
||||||
|
|
||||||
type Label struct {
|
type Label struct {
|
||||||
|
|
@ -177,16 +199,18 @@ type Label struct {
|
||||||
Def *Node
|
Def *Node
|
||||||
Use *NodeList
|
Use *NodeList
|
||||||
Link *Label
|
Link *Label
|
||||||
Gotopc *obj.Prog
|
|
||||||
Labelpc *obj.Prog
|
// for use during gen
|
||||||
Breakpc *obj.Prog
|
Gotopc *obj.Prog // pointer to unresolved gotos
|
||||||
Continpc *obj.Prog
|
Labelpc *obj.Prog // pointer to code
|
||||||
|
Breakpc *obj.Prog // pointer to code
|
||||||
|
Continpc *obj.Prog // pointer to code
|
||||||
}
|
}
|
||||||
|
|
||||||
type InitEntry struct {
|
type InitEntry struct {
|
||||||
Xoffset int64
|
Xoffset int64 // struct, array only
|
||||||
Key *Node
|
Key *Node // map only
|
||||||
Expr *Node
|
Expr *Node // bytes of run-time computed expressions
|
||||||
}
|
}
|
||||||
|
|
||||||
type InitPlan struct {
|
type InitPlan struct {
|
||||||
|
|
@ -205,14 +229,14 @@ const (
|
||||||
EscNever
|
EscNever
|
||||||
EscBits = 3
|
EscBits = 3
|
||||||
EscMask = (1 << EscBits) - 1
|
EscMask = (1 << EscBits) - 1
|
||||||
EscContentEscapes = 1 << EscBits
|
EscContentEscapes = 1 << EscBits // value obtained by indirect of parameter escapes to some returned result
|
||||||
EscReturnBits = EscBits + 1
|
EscReturnBits = EscBits + 1
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SymExport = 1 << 0
|
SymExport = 1 << 0 // to be exported
|
||||||
SymPackage = 1 << 1
|
SymPackage = 1 << 1
|
||||||
SymExported = 1 << 2
|
SymExported = 1 << 2 // already written out by export
|
||||||
SymUniq = 1 << 3
|
SymUniq = 1 << 3
|
||||||
SymSiggen = 1 << 4
|
SymSiggen = 1 << 4
|
||||||
SymAsm = 1 << 5
|
SymAsm = 1 << 5
|
||||||
|
|
@ -231,6 +255,7 @@ type Iter struct {
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Txxx = iota
|
Txxx = iota
|
||||||
|
|
||||||
TINT8
|
TINT8
|
||||||
TUINT8
|
TUINT8
|
||||||
TINT16
|
TINT16
|
||||||
|
|
@ -242,13 +267,18 @@ const (
|
||||||
TINT
|
TINT
|
||||||
TUINT
|
TUINT
|
||||||
TUINTPTR
|
TUINTPTR
|
||||||
|
|
||||||
TCOMPLEX64
|
TCOMPLEX64
|
||||||
TCOMPLEX128
|
TCOMPLEX128
|
||||||
|
|
||||||
TFLOAT32
|
TFLOAT32
|
||||||
TFLOAT64
|
TFLOAT64
|
||||||
|
|
||||||
TBOOL
|
TBOOL
|
||||||
|
|
||||||
TPTR32
|
TPTR32
|
||||||
TPTR64
|
TPTR64
|
||||||
|
|
||||||
TFUNC
|
TFUNC
|
||||||
TARRAY
|
TARRAY
|
||||||
T_old_DARRAY
|
T_old_DARRAY
|
||||||
|
|
@ -261,17 +291,23 @@ const (
|
||||||
TANY
|
TANY
|
||||||
TSTRING
|
TSTRING
|
||||||
TUNSAFEPTR
|
TUNSAFEPTR
|
||||||
|
|
||||||
|
// pseudo-types for literals
|
||||||
TIDEAL
|
TIDEAL
|
||||||
TNIL
|
TNIL
|
||||||
TBLANK
|
TBLANK
|
||||||
|
|
||||||
|
// pseudo-type for frame layout
|
||||||
TFUNCARGS
|
TFUNCARGS
|
||||||
TCHANARGS
|
TCHANARGS
|
||||||
TINTERMETH
|
TINTERMETH
|
||||||
|
|
||||||
NTYPE
|
NTYPE
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
CTxxx = iota
|
CTxxx = iota
|
||||||
|
|
||||||
CTINT
|
CTINT
|
||||||
CTRUNE
|
CTRUNE
|
||||||
CTFLT
|
CTFLT
|
||||||
|
|
@ -282,6 +318,8 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
/* types of channel */
|
||||||
|
/* must match ../../pkg/nreflect/type.go:/Chandir */
|
||||||
Cxxx = 0
|
Cxxx = 0
|
||||||
Crecv = 1 << 0
|
Crecv = 1 << 0
|
||||||
Csend = 1 << 1
|
Csend = 1 << 1
|
||||||
|
|
@ -291,28 +329,30 @@ const (
|
||||||
// declaration context
|
// declaration context
|
||||||
const (
|
const (
|
||||||
Pxxx = iota
|
Pxxx = iota
|
||||||
PEXTERN
|
PEXTERN // global variable
|
||||||
PAUTO
|
PAUTO // local variables
|
||||||
PPARAM
|
PPARAM // input arguments
|
||||||
PPARAMOUT
|
PPARAMOUT // output results
|
||||||
PPARAMREF
|
PPARAMREF // closure variable reference
|
||||||
PFUNC
|
PFUNC // global function
|
||||||
PDISCARD
|
|
||||||
PHEAP = 1 << 7
|
PDISCARD // discard during parse of duplicate import
|
||||||
|
|
||||||
|
PHEAP = 1 << 7 // an extra bit to identify an escaped variable
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Etop = 1 << 1
|
Etop = 1 << 1 // evaluated at statement level
|
||||||
Erv = 1 << 2
|
Erv = 1 << 2 // evaluated in value context
|
||||||
Etype = 1 << 3
|
Etype = 1 << 3
|
||||||
Ecall = 1 << 4
|
Ecall = 1 << 4 // call-only expressions are ok
|
||||||
Efnstruct = 1 << 5
|
Efnstruct = 1 << 5 // multivalue function returns are ok
|
||||||
Eiota = 1 << 6
|
Eiota = 1 << 6 // iota is ok
|
||||||
Easgn = 1 << 7
|
Easgn = 1 << 7 // assigning to expression
|
||||||
Eindir = 1 << 8
|
Eindir = 1 << 8 // indirecting through expression
|
||||||
Eaddr = 1 << 9
|
Eaddr = 1 << 9 // taking address of expression
|
||||||
Eproc = 1 << 10
|
Eproc = 1 << 10 // inside a go statement
|
||||||
Ecomplit = 1 << 11
|
Ecomplit = 1 << 11 // type in composite literal
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -364,8 +404,8 @@ type Io struct {
|
||||||
eofnl int
|
eofnl int
|
||||||
last int
|
last int
|
||||||
peekc int
|
peekc int
|
||||||
peekc1 int
|
peekc1 int // second peekc for ...
|
||||||
cp string
|
cp string // used for content when bin==nil
|
||||||
importsafe bool
|
importsafe bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -383,14 +423,18 @@ type Idir struct {
|
||||||
* smagic and umagic
|
* smagic and umagic
|
||||||
*/
|
*/
|
||||||
type Magic struct {
|
type Magic struct {
|
||||||
W int
|
W int // input for both - width
|
||||||
S int
|
S int // output for both - shift
|
||||||
Bad int
|
Bad int // output for both - unexpected failure
|
||||||
Sd int64
|
|
||||||
Sm int64
|
// magic multiplier for signed literal divisors
|
||||||
Ud uint64
|
Sd int64 // input - literal divisor
|
||||||
Um uint64
|
Sm int64 // output - multiplier
|
||||||
Ua int
|
|
||||||
|
// magic multiplier for unsigned literal divisors
|
||||||
|
Ud uint64 // input - literal divisor
|
||||||
|
Um uint64 // output - multiplier
|
||||||
|
Ua int // output - adder
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -670,24 +714,30 @@ var Disable_checknil int
|
||||||
var zerosize int64
|
var zerosize int64
|
||||||
|
|
||||||
type Flow struct {
|
type Flow struct {
|
||||||
Prog *obj.Prog
|
Prog *obj.Prog // actual instruction
|
||||||
P1 *Flow
|
P1 *Flow // predecessors of this instruction: p1,
|
||||||
P2 *Flow
|
P2 *Flow // and then p2 linked though p2link.
|
||||||
P2link *Flow
|
P2link *Flow
|
||||||
S1 *Flow
|
S1 *Flow // successors of this instruction (at most two: s1 and s2).
|
||||||
S2 *Flow
|
S2 *Flow
|
||||||
Link *Flow
|
Link *Flow // next instruction in function code
|
||||||
Active int32
|
|
||||||
Id int32
|
Active int32 // usable by client
|
||||||
Rpo int32
|
|
||||||
Loop uint16
|
Id int32 // sequence number in flow graph
|
||||||
Refset uint8
|
Rpo int32 // reverse post ordering
|
||||||
Data interface{}
|
Loop uint16 // x5 for every loop
|
||||||
|
Refset uint8 // diagnostic generated
|
||||||
|
|
||||||
|
Data interface{} // for use by client
|
||||||
}
|
}
|
||||||
|
|
||||||
type Graph struct {
|
type Graph struct {
|
||||||
Start *Flow
|
Start *Flow
|
||||||
Num int
|
Num int
|
||||||
|
|
||||||
|
// After calling flowrpo, rpo lists the flow nodes in reverse postorder,
|
||||||
|
// and each non-dead Flow node f has g->rpo[f->rpo] == f.
|
||||||
Rpo []*Flow
|
Rpo []*Flow
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -695,41 +745,62 @@ type Graph struct {
|
||||||
* interface to back end
|
* interface to back end
|
||||||
*/
|
*/
|
||||||
type ProgInfo struct {
|
type ProgInfo struct {
|
||||||
Flags uint32
|
Flags uint32 // the bits below
|
||||||
Reguse uint64
|
Reguse uint64 // registers implicitly used by this instruction
|
||||||
Regset uint64
|
Regset uint64 // registers implicitly set by this instruction
|
||||||
Regindex uint64
|
Regindex uint64 // registers used by addressing mode
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA.
|
||||||
Pseudo = 1 << 1
|
Pseudo = 1 << 1
|
||||||
|
|
||||||
|
// There's nothing to say about the instruction,
|
||||||
|
// but it's still okay to see.
|
||||||
OK = 1 << 2
|
OK = 1 << 2
|
||||||
|
|
||||||
|
// Size of right-side write, or right-side read if no write.
|
||||||
SizeB = 1 << 3
|
SizeB = 1 << 3
|
||||||
SizeW = 1 << 4
|
SizeW = 1 << 4
|
||||||
SizeL = 1 << 5
|
SizeL = 1 << 5
|
||||||
SizeQ = 1 << 6
|
SizeQ = 1 << 6
|
||||||
SizeF = 1 << 7
|
SizeF = 1 << 7
|
||||||
SizeD = 1 << 8
|
SizeD = 1 << 8
|
||||||
|
|
||||||
|
// Left side (Prog.from): address taken, read, write.
|
||||||
LeftAddr = 1 << 9
|
LeftAddr = 1 << 9
|
||||||
LeftRead = 1 << 10
|
LeftRead = 1 << 10
|
||||||
LeftWrite = 1 << 11
|
LeftWrite = 1 << 11
|
||||||
|
|
||||||
|
// Register in middle (Prog.reg); only ever read. (arm, ppc64)
|
||||||
RegRead = 1 << 12
|
RegRead = 1 << 12
|
||||||
CanRegRead = 1 << 13
|
CanRegRead = 1 << 13
|
||||||
|
|
||||||
|
// Right side (Prog.to): address taken, read, write.
|
||||||
RightAddr = 1 << 14
|
RightAddr = 1 << 14
|
||||||
RightRead = 1 << 15
|
RightRead = 1 << 15
|
||||||
RightWrite = 1 << 16
|
RightWrite = 1 << 16
|
||||||
Move = 1 << 17
|
|
||||||
Conv = 1 << 18
|
// Instruction kinds
|
||||||
Cjmp = 1 << 19
|
Move = 1 << 17 // straight move
|
||||||
Break = 1 << 20
|
Conv = 1 << 18 // size conversion
|
||||||
Call = 1 << 21
|
Cjmp = 1 << 19 // conditional jump
|
||||||
Jump = 1 << 22
|
Break = 1 << 20 // breaks control flow (no fallthrough)
|
||||||
Skip = 1 << 23
|
Call = 1 << 21 // function call
|
||||||
|
Jump = 1 << 22 // jump
|
||||||
|
Skip = 1 << 23 // data instruction
|
||||||
|
|
||||||
|
// Set, use, or kill of carry bit.
|
||||||
|
// Kill means we never look at the carry bit after this kind of instruction.
|
||||||
SetCarry = 1 << 24
|
SetCarry = 1 << 24
|
||||||
UseCarry = 1 << 25
|
UseCarry = 1 << 25
|
||||||
KillCarry = 1 << 26
|
KillCarry = 1 << 26
|
||||||
ShiftCX = 1 << 27
|
|
||||||
ImulAXDX = 1 << 28
|
// Special cases for register use. (amd64, 386)
|
||||||
|
ShiftCX = 1 << 27 // possible shift by CX
|
||||||
|
ImulAXDX = 1 << 28 // possible multiply into DX:AX
|
||||||
|
|
||||||
|
// Instruction updates whichever of from/to is type D_OREG. (ppc64)
|
||||||
PostInc = 1 << 29
|
PostInc = 1 << 29
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,7 @@ func dumpdata() {
|
||||||
Clearp(Pc)
|
Clearp(Pc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fixup instructions after allocauto (formerly compactframe) has moved all autos around.
|
||||||
func fixautoused(p *obj.Prog) {
|
func fixautoused(p *obj.Prog) {
|
||||||
for lp := &p; ; {
|
for lp := &p; ; {
|
||||||
p = *lp
|
p = *lp
|
||||||
|
|
@ -258,6 +259,7 @@ func Isfat(t *Type) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sweep the prog list to mark any used nodes.
|
||||||
func markautoused(p *obj.Prog) {
|
func markautoused(p *obj.Prog) {
|
||||||
for ; p != nil; p = p.Link {
|
for ; p != nil; p = p.Link {
|
||||||
if p.As == obj.ATYPE || p.As == obj.AVARDEF || p.As == obj.AVARKILL {
|
if p.As == obj.ATYPE || p.As == obj.AVARDEF || p.As == obj.AVARKILL {
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,9 @@ import (
|
||||||
|
|
||||||
// Order holds state during the ordering process.
|
// Order holds state during the ordering process.
|
||||||
type Order struct {
|
type Order struct {
|
||||||
out *NodeList
|
out *NodeList // list of generated statements
|
||||||
temp *NodeList
|
temp *NodeList // head of stack of temporary variables
|
||||||
free *NodeList
|
free *NodeList // free list of NodeList* structs (for use in temp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Order rewrites fn->nbody to apply the ordering constraints
|
// Order rewrites fn->nbody to apply the ordering constraints
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,17 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Garbage collector liveness bitmap generation.
|
||||||
|
|
||||||
|
// The command line flag -live causes this code to print debug information.
|
||||||
|
// The levels are:
|
||||||
|
//
|
||||||
|
// -live (aka -live=1): print liveness lists as code warnings at safe points
|
||||||
|
// -live=2: print an assembly listing with liveness annotations
|
||||||
|
// -live=3: print information during each computation phase (much chattier)
|
||||||
|
//
|
||||||
|
// Each level includes the earlier output as well.
|
||||||
|
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -34,18 +45,36 @@ const (
|
||||||
// ...
|
// ...
|
||||||
// }
|
// }
|
||||||
type BasicBlock struct {
|
type BasicBlock struct {
|
||||||
pred []*BasicBlock
|
pred []*BasicBlock // predecessors; if none, probably start of CFG
|
||||||
succ []*BasicBlock
|
succ []*BasicBlock // successors; if none, probably ends in return statement
|
||||||
first *obj.Prog
|
first *obj.Prog // first instruction in block
|
||||||
last *obj.Prog
|
last *obj.Prog // last instruction in block
|
||||||
rpo int
|
rpo int // reverse post-order number (also index in cfg)
|
||||||
mark int
|
mark int // mark bit for traversals
|
||||||
lastbitmapindex int
|
lastbitmapindex int // for livenessepilogue
|
||||||
|
|
||||||
|
// Summary sets of block effects.
|
||||||
|
|
||||||
|
// Computed during livenessprologue using only the content of
|
||||||
|
// individual blocks:
|
||||||
|
//
|
||||||
|
// uevar: upward exposed variables (used before set in block)
|
||||||
|
// varkill: killed variables (set in block)
|
||||||
|
// avarinit: addrtaken variables set or used (proof of initialization)
|
||||||
uevar Bvec
|
uevar Bvec
|
||||||
varkill Bvec
|
varkill Bvec
|
||||||
|
avarinit Bvec
|
||||||
|
|
||||||
|
// Computed during livenesssolve using control flow information:
|
||||||
|
//
|
||||||
|
// livein: variables live at block entry
|
||||||
|
// liveout: variables live at block exit
|
||||||
|
// avarinitany: addrtaken variables possibly initialized at block exit
|
||||||
|
// (initialized in block or at exit from any predecessor block)
|
||||||
|
// avarinitall: addrtaken variables certainly initialized at block exit
|
||||||
|
// (initialized in block or at exit from all predecessor blocks)
|
||||||
livein Bvec
|
livein Bvec
|
||||||
liveout Bvec
|
liveout Bvec
|
||||||
avarinit Bvec
|
|
||||||
avarinitany Bvec
|
avarinitany Bvec
|
||||||
avarinitall Bvec
|
avarinitall Bvec
|
||||||
}
|
}
|
||||||
|
|
@ -56,6 +85,9 @@ type Liveness struct {
|
||||||
ptxt *obj.Prog
|
ptxt *obj.Prog
|
||||||
vars []*Node
|
vars []*Node
|
||||||
cfg []*BasicBlock
|
cfg []*BasicBlock
|
||||||
|
|
||||||
|
// An array with a bit vector for each safe point tracking live pointers
|
||||||
|
// in the arguments and locals area, indexed by bb.rpo.
|
||||||
argslivepointers []Bvec
|
argslivepointers []Bvec
|
||||||
livepointers []Bvec
|
livepointers []Bvec
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,16 +79,25 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Reg struct {
|
type Reg struct {
|
||||||
set Bits
|
set Bits // regopt variables written by this instruction.
|
||||||
use1 Bits
|
use1 Bits // regopt variables read by prog->from.
|
||||||
use2 Bits
|
use2 Bits // 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).
|
||||||
refbehind Bits
|
refbehind Bits
|
||||||
refahead Bits
|
refahead Bits
|
||||||
|
|
||||||
|
// calahead/calbehind are similar, but for variables in
|
||||||
|
// instructions that are reachable after hitting at least one
|
||||||
|
// CALL.
|
||||||
calbehind Bits
|
calbehind Bits
|
||||||
calahead Bits
|
calahead Bits
|
||||||
|
|
||||||
regdiff Bits
|
regdiff Bits
|
||||||
act Bits
|
act Bits
|
||||||
regu uint64
|
regu uint64 // register used bitmap
|
||||||
}
|
}
|
||||||
|
|
||||||
type Rgn struct {
|
type Rgn struct {
|
||||||
|
|
@ -639,14 +648,14 @@ func Uniqs(r *Flow) *Flow {
|
||||||
|
|
||||||
type TempVar struct {
|
type TempVar struct {
|
||||||
node *Node
|
node *Node
|
||||||
def *Flow
|
def *Flow // definition of temp var
|
||||||
use *Flow
|
use *Flow // use list, chained through Flow.data
|
||||||
freelink *TempVar
|
freelink *TempVar // next free temp in Type.opt list
|
||||||
merge *TempVar
|
merge *TempVar // merge var with this one
|
||||||
start int64
|
start int64 // smallest Prog.pc in live range
|
||||||
end int64
|
end int64 // largest Prog.pc in live range
|
||||||
addr uint8
|
addr uint8 // address taken - no accurate end
|
||||||
removed uint8
|
removed uint8 // removed from program
|
||||||
}
|
}
|
||||||
|
|
||||||
type startcmp []*TempVar
|
type startcmp []*TempVar
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,13 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
func walkrange(n *Node) {
|
func walkrange(n *Node) {
|
||||||
|
// variable name conventions:
|
||||||
|
// ohv1, hv1, hv2: hidden (old) val 1, 2
|
||||||
|
// ha, hit: hidden aggregate, iterator
|
||||||
|
// hn, hp: hidden len, pointer
|
||||||
|
// hb: hidden bool
|
||||||
|
// a, v1, v2: not hidden aggregate, val 1, 2
|
||||||
|
|
||||||
t := n.Type
|
t := n.Type
|
||||||
|
|
||||||
a := n.Right
|
a := n.Right
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ package gc
|
||||||
// node with Op=ONAME for a given instance of a variable x.
|
// node with Op=ONAME for a given instance of a variable x.
|
||||||
// The same is true for Op=OTYPE and Op=OLITERAL.
|
// The same is true for Op=OTYPE and Op=OLITERAL.
|
||||||
type Node struct {
|
type Node struct {
|
||||||
|
// Tree structure.
|
||||||
|
// Generic recursive walks should follow these fields.
|
||||||
Left *Node
|
Left *Node
|
||||||
Right *Node
|
Right *Node
|
||||||
Ntest *Node
|
Ntest *Node
|
||||||
|
|
@ -20,22 +22,23 @@ type Node struct {
|
||||||
Nelse *NodeList
|
Nelse *NodeList
|
||||||
List *NodeList
|
List *NodeList
|
||||||
Rlist *NodeList
|
Rlist *NodeList
|
||||||
|
|
||||||
Op uint8
|
Op uint8
|
||||||
Nointerface bool
|
Nointerface bool
|
||||||
Ullman uint8
|
Ullman uint8 // sethi/ullman number
|
||||||
Addable uint8
|
Addable uint8 // type of addressability - 0 is not addressable
|
||||||
Trecur uint8
|
Trecur uint8 // to detect loops
|
||||||
Etype uint8
|
Etype uint8 // op for OASOP, etype for OTYPE, exclam for export
|
||||||
Bounded bool
|
Bounded bool // bounds check unnecessary
|
||||||
Class uint8
|
Class uint8 // PPARAM, PAUTO, PEXTERN, etc
|
||||||
Method uint8
|
Method uint8 // OCALLMETH name
|
||||||
Embedded uint8
|
Embedded uint8 // ODCLFIELD embedded type
|
||||||
Colas uint8
|
Colas uint8 // OAS resulting from :=
|
||||||
Diag uint8
|
Diag uint8 // already printed error about this
|
||||||
Noescape bool
|
Noescape bool // func arguments do not escape
|
||||||
Nosplit bool
|
Nosplit bool // func should not execute on separate stack
|
||||||
Builtin uint8
|
Builtin uint8 // built-in name, like len or close
|
||||||
Nowritebarrier bool
|
Nowritebarrier bool // emit compiler error instead of write barrier
|
||||||
Walkdef uint8
|
Walkdef uint8
|
||||||
Typecheck uint8
|
Typecheck uint8
|
||||||
Local uint8
|
Local uint8
|
||||||
|
|
@ -45,219 +48,255 @@ type Node struct {
|
||||||
Isddd uint8
|
Isddd uint8
|
||||||
Readonly uint8
|
Readonly uint8
|
||||||
Implicit uint8
|
Implicit uint8
|
||||||
Addrtaken uint8
|
Addrtaken uint8 // address taken, even if not moved to heap
|
||||||
Assigned uint8
|
Assigned uint8 // is the variable ever assigned to
|
||||||
Captured uint8
|
Captured uint8 // is the variable captured by a closure
|
||||||
Byval uint8
|
Byval uint8 // is the variable captured by value or by reference
|
||||||
Dupok uint8
|
Dupok uint8 // duplicate definitions ok (for func)
|
||||||
Wrapper uint8
|
Wrapper uint8 // is method wrapper (for func)
|
||||||
Reslice uint8
|
Reslice uint8 // this is a reslice x = x[0:y] or x = append(x, ...)
|
||||||
Likely int8
|
Likely int8 // likeliness of if statement
|
||||||
Hasbreak uint8
|
Hasbreak uint8 // has break statement
|
||||||
Needzero bool
|
Needzero bool // if it contains pointers, needs to be zeroed on function entry
|
||||||
Needctxt bool
|
Needctxt bool // function uses context register (has closure variables)
|
||||||
Esc uint
|
Esc uint // EscXXX
|
||||||
Funcdepth int
|
Funcdepth int
|
||||||
|
|
||||||
|
// most nodes
|
||||||
Type *Type
|
Type *Type
|
||||||
Orig *Node
|
Orig *Node // original form, for printing, and tracking copies of ONAMEs
|
||||||
|
|
||||||
|
// func
|
||||||
Nname *Node
|
Nname *Node
|
||||||
Shortname *Node
|
Shortname *Node
|
||||||
Enter *NodeList
|
Enter *NodeList
|
||||||
Exit *NodeList
|
Exit *NodeList
|
||||||
Cvars *NodeList
|
Cvars *NodeList // closure params
|
||||||
Dcl *NodeList
|
Dcl *NodeList // autodcl for this func/closure
|
||||||
Inl *NodeList
|
Inl *NodeList // copy of the body for use in inlining
|
||||||
Inldcl *NodeList
|
Inldcl *NodeList // copy of dcl for use in inlining
|
||||||
Closgen int
|
Closgen int
|
||||||
Outerfunc *Node
|
Outerfunc *Node
|
||||||
|
|
||||||
|
// OLITERAL/OREGISTER
|
||||||
Val Val
|
Val Val
|
||||||
|
|
||||||
|
// ONAME
|
||||||
Ntype *Node
|
Ntype *Node
|
||||||
Defn *Node
|
Defn *Node // ONAME: initializing assignment; OLABEL: labeled statement
|
||||||
Pack *Node
|
Pack *Node // real package for import . names
|
||||||
Curfn *Node
|
Curfn *Node // function for local variables
|
||||||
Paramfld *Type
|
Paramfld *Type // TFIELD for this PPARAM; also for ODOT, curfn
|
||||||
Decldepth int
|
Decldepth int // declaration loop depth, increased for every loop or label
|
||||||
Heapaddr *Node
|
|
||||||
Outerexpr *Node
|
// ONAME func param with PHEAP
|
||||||
Stackparam *Node
|
Heapaddr *Node // temp holding heap address of param
|
||||||
Alloc *Node
|
Outerexpr *Node // expression copied into closure for variable
|
||||||
Outer *Node
|
Stackparam *Node // OPARAM node referring to stack copy of param
|
||||||
Closure *Node
|
Alloc *Node // allocation call
|
||||||
Top int
|
|
||||||
|
// ONAME closure param with PPARAMREF
|
||||||
|
Outer *Node // outer PPARAMREF in nested closure
|
||||||
|
Closure *Node // ONAME/PHEAP <-> ONAME/PPARAMREF
|
||||||
|
Top int // top context (Ecall, Eproc, etc)
|
||||||
|
|
||||||
|
// ONAME substitute while inlining
|
||||||
Inlvar *Node
|
Inlvar *Node
|
||||||
|
|
||||||
|
// OPACK
|
||||||
Pkg *Pkg
|
Pkg *Pkg
|
||||||
|
|
||||||
|
// OARRAYLIT, OMAPLIT, OSTRUCTLIT.
|
||||||
Initplan *InitPlan
|
Initplan *InitPlan
|
||||||
Escflowsrc *NodeList
|
|
||||||
Escretval *NodeList
|
// Escape analysis.
|
||||||
Escloopdepth int
|
Escflowsrc *NodeList // flow(this, src)
|
||||||
Sym *Sym
|
Escretval *NodeList // on OCALLxxx, list of dummy return values
|
||||||
InlCost int32
|
Escloopdepth int // -1: global, 0: return variables, 1:function top level, increased inside function for every loop or label to mark scopes
|
||||||
|
|
||||||
|
Sym *Sym // various
|
||||||
|
InlCost int32 // unique name for OTYPE/ONAME
|
||||||
Vargen int32
|
Vargen int32
|
||||||
Lineno int32
|
Lineno int32
|
||||||
Endlineno int32
|
Endlineno int32
|
||||||
Xoffset int64
|
Xoffset int64
|
||||||
Stkdelta int64
|
Stkdelta int64 // offset added by stack frame compaction phase.
|
||||||
Ostk int32
|
Ostk int32
|
||||||
Iota int32
|
Iota int32
|
||||||
Walkgen uint32
|
Walkgen uint32
|
||||||
Esclevel int32
|
Esclevel int32
|
||||||
Opt interface{}
|
Opt interface{} // for optimization passes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Node ops.
|
// Node ops.
|
||||||
const (
|
const (
|
||||||
OXXX = iota
|
OXXX = iota
|
||||||
ONAME
|
|
||||||
ONONAME
|
// names
|
||||||
OTYPE
|
ONAME // var, const or func name
|
||||||
OPACK
|
ONONAME // unnamed arg or return value: f(int, string) (int, error) { etc }
|
||||||
OLITERAL
|
OTYPE // type name
|
||||||
OADD
|
OPACK // import
|
||||||
OSUB
|
OLITERAL // literal
|
||||||
OOR
|
|
||||||
OXOR
|
// expressions
|
||||||
OADDSTR
|
OADD // x + y
|
||||||
OADDR
|
OSUB // x - y
|
||||||
OANDAND
|
OOR // x | y
|
||||||
OAPPEND
|
OXOR // x ^ y
|
||||||
OARRAYBYTESTR
|
OADDSTR // s + "foo"
|
||||||
OARRAYBYTESTRTMP
|
OADDR // &x
|
||||||
OARRAYRUNESTR
|
OANDAND // b0 && b1
|
||||||
OSTRARRAYBYTE
|
OAPPEND // append
|
||||||
OSTRARRAYBYTETMP
|
OARRAYBYTESTR // string(bytes)
|
||||||
OSTRARRAYRUNE
|
OARRAYBYTESTRTMP // string(bytes) ephemeral
|
||||||
OAS
|
OARRAYRUNESTR // string(runes)
|
||||||
OAS2
|
OSTRARRAYBYTE // []byte(s)
|
||||||
OAS2FUNC
|
OSTRARRAYBYTETMP // []byte(s) ephemeral
|
||||||
OAS2RECV
|
OSTRARRAYRUNE // []rune(s)
|
||||||
OAS2MAPR
|
OAS // x = y or x := y
|
||||||
OAS2DOTTYPE
|
OAS2 // x, y, z = xx, yy, zz
|
||||||
OASOP
|
OAS2FUNC // x, y = f()
|
||||||
OCALL
|
OAS2RECV // x, ok = <-c
|
||||||
OCALLFUNC
|
OAS2MAPR // x, ok = m["foo"]
|
||||||
OCALLMETH
|
OAS2DOTTYPE // x, ok = I.(int)
|
||||||
OCALLINTER
|
OASOP // x += y
|
||||||
OCALLPART
|
OCALL // function call, method call or type conversion, possibly preceded by defer or go.
|
||||||
OCAP
|
OCALLFUNC // f()
|
||||||
OCLOSE
|
OCALLMETH // t.Method()
|
||||||
OCLOSURE
|
OCALLINTER // err.Error()
|
||||||
OCMPIFACE
|
OCALLPART // t.Method (without ())
|
||||||
OCMPSTR
|
OCAP // cap
|
||||||
OCOMPLIT
|
OCLOSE // close
|
||||||
OMAPLIT
|
OCLOSURE // f = func() { etc }
|
||||||
OSTRUCTLIT
|
OCMPIFACE // err1 == err2
|
||||||
OARRAYLIT
|
OCMPSTR // s1 == s2
|
||||||
OPTRLIT
|
OCOMPLIT // composite literal, typechecking may convert to a more specific OXXXLIT.
|
||||||
OCONV
|
OMAPLIT // M{"foo":3, "bar":4}
|
||||||
OCONVIFACE
|
OSTRUCTLIT // T{x:3, y:4}
|
||||||
OCONVNOP
|
OARRAYLIT // [2]int{3, 4}
|
||||||
OCOPY
|
OPTRLIT // &T{x:3, y:4}
|
||||||
ODCL
|
OCONV // var i int; var u uint; i = int(u)
|
||||||
ODCLFUNC
|
OCONVIFACE // I(t)
|
||||||
ODCLFIELD
|
OCONVNOP // type Int int; var i int; var j Int; i = int(j)
|
||||||
ODCLCONST
|
OCOPY // copy
|
||||||
ODCLTYPE
|
ODCL // var x int
|
||||||
ODELETE
|
ODCLFUNC // func f() or func (r) f()
|
||||||
ODOT
|
ODCLFIELD // struct field, interface field, or func/method argument/return value.
|
||||||
ODOTPTR
|
ODCLCONST // const pi = 3.14
|
||||||
ODOTMETH
|
ODCLTYPE // type Int int
|
||||||
ODOTINTER
|
ODELETE // delete
|
||||||
OXDOT
|
ODOT // t.x
|
||||||
ODOTTYPE
|
ODOTPTR // p.x that is implicitly (*p).x
|
||||||
ODOTTYPE2
|
ODOTMETH // t.Method
|
||||||
OEQ
|
ODOTINTER // err.Error
|
||||||
ONE
|
OXDOT // t.x, typechecking may convert to a more specific ODOTXXX.
|
||||||
OLT
|
ODOTTYPE // e = err.(MyErr)
|
||||||
OLE
|
ODOTTYPE2 // e, ok = err.(MyErr)
|
||||||
OGE
|
OEQ // x == y
|
||||||
OGT
|
ONE // x != y
|
||||||
OIND
|
OLT // x < y
|
||||||
OINDEX
|
OLE // x <= y
|
||||||
OINDEXMAP
|
OGE // x >= y
|
||||||
OKEY
|
OGT // x > y
|
||||||
OPARAM
|
OIND // *p
|
||||||
OLEN
|
OINDEX // a[i]
|
||||||
OMAKE
|
OINDEXMAP // m[s]
|
||||||
OMAKECHAN
|
OKEY // The x:3 in t{x:3, y:4}, the 1:2 in a[1:2], the 2:20 in [3]int{2:20}, etc.
|
||||||
OMAKEMAP
|
OPARAM // The on-stack copy of a parameter or return value that escapes.
|
||||||
OMAKESLICE
|
OLEN // len
|
||||||
OMUL
|
OMAKE // make, typechecking may convert to a more specific OMAKEXXX.
|
||||||
ODIV
|
OMAKECHAN // make(chan int)
|
||||||
OMOD
|
OMAKEMAP // make(map[string]int)
|
||||||
OLSH
|
OMAKESLICE // make([]int, 0)
|
||||||
ORSH
|
OMUL // *
|
||||||
OAND
|
ODIV // x / y
|
||||||
OANDNOT
|
OMOD // x % y
|
||||||
ONEW
|
OLSH // x << u
|
||||||
ONOT
|
ORSH // x >> u
|
||||||
OCOM
|
OAND // x & y
|
||||||
OPLUS
|
OANDNOT // x &^ y
|
||||||
OMINUS
|
ONEW // new
|
||||||
OOROR
|
ONOT // !b
|
||||||
OPANIC
|
OCOM // ^x
|
||||||
OPRINT
|
OPLUS // +x
|
||||||
OPRINTN
|
OMINUS // -y
|
||||||
OPAREN
|
OOROR // b1 || b2
|
||||||
OSEND
|
OPANIC // panic
|
||||||
OSLICE
|
OPRINT // print
|
||||||
OSLICEARR
|
OPRINTN // println
|
||||||
OSLICESTR
|
OPAREN // (x)
|
||||||
OSLICE3
|
OSEND // c <- x
|
||||||
OSLICE3ARR
|
OSLICE // v[1:2], typechecking may convert to a more specific OSLICEXXX.
|
||||||
ORECOVER
|
OSLICEARR // a[1:2]
|
||||||
ORECV
|
OSLICESTR // s[1:2]
|
||||||
ORUNESTR
|
OSLICE3 // v[1:2:3], typechecking may convert to OSLICE3ARR.
|
||||||
OSELRECV
|
OSLICE3ARR // a[1:2:3]
|
||||||
OSELRECV2
|
ORECOVER // recover
|
||||||
OIOTA
|
ORECV // <-c
|
||||||
OREAL
|
ORUNESTR // string(i)
|
||||||
OIMAG
|
OSELRECV // case x = <-c:
|
||||||
OCOMPLEX
|
OSELRECV2 // case x, ok = <-c:
|
||||||
OBLOCK
|
OIOTA // iota
|
||||||
OBREAK
|
OREAL // real
|
||||||
OCASE
|
OIMAG // imag
|
||||||
OXCASE
|
OCOMPLEX // complex
|
||||||
OCONTINUE
|
|
||||||
ODEFER
|
// statements
|
||||||
OEMPTY
|
OBLOCK // block of code
|
||||||
OFALL
|
OBREAK // break
|
||||||
OXFALL
|
OCASE // case, after being verified by swt.c's casebody.
|
||||||
OFOR
|
OXCASE // case, before verification.
|
||||||
OGOTO
|
OCONTINUE // continue
|
||||||
OIF
|
ODEFER // defer
|
||||||
OLABEL
|
OEMPTY // no-op
|
||||||
OPROC
|
OFALL // fallthrough, after being verified by swt.c's casebody.
|
||||||
ORANGE
|
OXFALL // fallthrough, before verification.
|
||||||
ORETURN
|
OFOR // for
|
||||||
OSELECT
|
OGOTO // goto
|
||||||
OSWITCH
|
OIF // if
|
||||||
OTYPESW
|
OLABEL // label:
|
||||||
OTCHAN
|
OPROC // go
|
||||||
OTMAP
|
ORANGE // range
|
||||||
OTSTRUCT
|
ORETURN // return
|
||||||
OTINTER
|
OSELECT // select
|
||||||
OTFUNC
|
OSWITCH // switch x
|
||||||
OTARRAY
|
OTYPESW // switch err.(type)
|
||||||
ODDD
|
|
||||||
ODDDARG
|
// types
|
||||||
OINLCALL
|
OTCHAN // chan int
|
||||||
OEFACE
|
OTMAP // map[string]int
|
||||||
OITAB
|
OTSTRUCT // struct{}
|
||||||
OSPTR
|
OTINTER // interface{}
|
||||||
OCLOSUREVAR
|
OTFUNC // func()
|
||||||
OCFUNC
|
OTARRAY // []int, [8]int, [N]int or [...]int
|
||||||
OCHECKNIL
|
|
||||||
OVARKILL
|
// misc
|
||||||
OREGISTER
|
ODDD // func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}.
|
||||||
OINDREG
|
ODDDARG // func f(args ...int), introduced by escape analysis.
|
||||||
OCMP
|
OINLCALL // intermediary representation of an inlined call.
|
||||||
ODEC
|
OEFACE // itable and data words of an empty-interface value.
|
||||||
OINC
|
OITAB // itable word of an interface value.
|
||||||
OEXTEND
|
OSPTR // base pointer of a slice or string.
|
||||||
OHMUL
|
OCLOSUREVAR // variable reference at beginning of closure function
|
||||||
OLROT
|
OCFUNC // reference to c function pointer (not go func value)
|
||||||
ORROTC
|
OCHECKNIL // emit code to ensure pointer/interface not nil
|
||||||
ORETJMP
|
OVARKILL // variable is dead
|
||||||
|
|
||||||
|
// thearch-specific registers
|
||||||
|
OREGISTER // a register, such as AX.
|
||||||
|
OINDREG // offset plus indirect of a register, such as 8(SP).
|
||||||
|
|
||||||
|
// 386/amd64-specific opcodes
|
||||||
|
OCMP // compare: ACMP.
|
||||||
|
ODEC // decrement: ADEC.
|
||||||
|
OINC // increment: AINC.
|
||||||
|
OEXTEND // extend: ACWD/ACDQ/ACQO.
|
||||||
|
OHMUL // high mul: AMUL/AIMUL for unsigned/signed (OMUL uses AIMUL for both).
|
||||||
|
OLROT // left rotate: AROL.
|
||||||
|
ORROTC // right rotate-carry: ARCR.
|
||||||
|
ORETJMP // return to other function
|
||||||
|
|
||||||
OEND
|
OEND
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -490,7 +490,7 @@ OpSwitch:
|
||||||
case OIND:
|
case OIND:
|
||||||
ntop := Erv | Etype
|
ntop := Erv | Etype
|
||||||
|
|
||||||
if top&Eaddr == 0 {
|
if top&Eaddr == 0 { // The *x in &*x is not an indirect.
|
||||||
ntop |= Eindir
|
ntop |= Eindir
|
||||||
}
|
}
|
||||||
ntop |= top & Ecomplit
|
ntop |= top & Ecomplit
|
||||||
|
|
|
||||||
|
|
@ -2950,10 +2950,9 @@ func appendslice(n *Node, init **NodeList) *Node {
|
||||||
nif.Ntest = Nod(OGT, nt, Nodintconst(0))
|
nif.Ntest = Nod(OGT, nt, Nodintconst(0))
|
||||||
|
|
||||||
// instantiate growslice(Type*, []any, int) []any
|
// instantiate growslice(Type*, []any, int) []any
|
||||||
fn := syslook("growslice", 1)
|
fn := syslook("growslice", 1) // growslice(<type>, old []T, n int64) (ret []T)
|
||||||
|
argtype(fn, s.Type.Type) // 1 old []any
|
||||||
argtype(fn, s.Type.Type)
|
argtype(fn, s.Type.Type) // 2 ret []any
|
||||||
argtype(fn, s.Type.Type)
|
|
||||||
|
|
||||||
// s = growslice(T, s, n)
|
// s = growslice(T, s, n)
|
||||||
nif.Nbody = list1(Nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(s.Type), s, nt)))
|
nif.Nbody = list1(Nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(s.Type), s, nt)))
|
||||||
|
|
@ -3774,8 +3773,8 @@ func walkdiv(np **Node, init **NodeList) {
|
||||||
// by a constant
|
// by a constant
|
||||||
w := int(nl.Type.Width * 8)
|
w := int(nl.Type.Width * 8)
|
||||||
|
|
||||||
s := 0
|
s := 0 // 1 if nr is negative.
|
||||||
pow := powtwo(nr)
|
pow := powtwo(nr) // if >= 0, nr is 1<<pow
|
||||||
if pow >= 1000 {
|
if pow >= 1000 {
|
||||||
// negative power of 2
|
// negative power of 2
|
||||||
s = 1
|
s = 1
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@ func decodetype_structfieldoffs(s *LSym, i int) int64 {
|
||||||
return int64(decode_inuxi(s.P[commonsize()+Thearch.Ptrsize+2*Thearch.Intsize+i*structfieldsize()+4*Thearch.Ptrsize:], Thearch.Intsize))
|
return int64(decode_inuxi(s.P[commonsize()+Thearch.Ptrsize+2*Thearch.Intsize+i*structfieldsize()+4*Thearch.Ptrsize:], Thearch.Intsize))
|
||||||
}
|
}
|
||||||
|
|
||||||
// InterfaceTYpe.methods.length
|
// InterfaceType.methods.length
|
||||||
func decodetype_ifacemethodcount(s *LSym) int64 {
|
func decodetype_ifacemethodcount(s *LSym) int64 {
|
||||||
return int64(decode_inuxi(s.P[commonsize()+Thearch.Ptrsize:], Thearch.Intsize))
|
return int64(decode_inuxi(s.P[commonsize()+Thearch.Ptrsize:], Thearch.Intsize))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,16 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// TODO/NICETOHAVE:
|
||||||
|
// - eliminate DW_CLS_ if not used
|
||||||
|
// - package info in compilation units
|
||||||
|
// - assign global variables and types to their packages
|
||||||
|
// - gdb uses c syntax, meaning clumsy quoting is needed for go identifiers. eg
|
||||||
|
// ptype struct '[]uint8' and qualifiers need to be quoted away
|
||||||
|
// - lexical scoping is lost, so gdb gets confused as to which 'main.i' you mean.
|
||||||
|
// - file:line info for variables
|
||||||
|
// - make strings a typedef so prettyprinters can see the underlying string type
|
||||||
|
|
||||||
package ld
|
package ld
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -176,7 +186,8 @@ const (
|
||||||
DW_AT_go_kind = 0x2900
|
DW_AT_go_kind = 0x2900
|
||||||
DW_AT_go_key = 0x2901
|
DW_AT_go_key = 0x2901
|
||||||
DW_AT_go_elem = 0x2902
|
DW_AT_go_elem = 0x2902
|
||||||
DW_AT_internal_location = 253
|
|
||||||
|
DW_AT_internal_location = 253 // params and locals; not emitted
|
||||||
)
|
)
|
||||||
|
|
||||||
// Index into the abbrevs table below.
|
// Index into the abbrevs table below.
|
||||||
|
|
@ -201,7 +212,7 @@ const (
|
||||||
DW_ABRV_IFACETYPE
|
DW_ABRV_IFACETYPE
|
||||||
DW_ABRV_MAPTYPE
|
DW_ABRV_MAPTYPE
|
||||||
DW_ABRV_PTRTYPE
|
DW_ABRV_PTRTYPE
|
||||||
DW_ABRV_BARE_PTRTYPE
|
DW_ABRV_BARE_PTRTYPE // only for void*, no DW_AT_type attr to please gdb 6.
|
||||||
DW_ABRV_SLICETYPE
|
DW_ABRV_SLICETYPE
|
||||||
DW_ABRV_STRINGTYPE
|
DW_ABRV_STRINGTYPE
|
||||||
DW_ABRV_STRUCTTYPE
|
DW_ABRV_STRUCTTYPE
|
||||||
|
|
@ -632,8 +643,8 @@ func dwarfhashstr(s string) uint32 {
|
||||||
|
|
||||||
type DWAttr struct {
|
type DWAttr struct {
|
||||||
link *DWAttr
|
link *DWAttr
|
||||||
atr uint16
|
atr uint16 // DW_AT_
|
||||||
cls uint8
|
cls uint8 // DW_CLS_
|
||||||
value int64
|
value int64
|
||||||
data interface{}
|
data interface{}
|
||||||
}
|
}
|
||||||
|
|
@ -643,9 +654,11 @@ type DWDie struct {
|
||||||
link *DWDie
|
link *DWDie
|
||||||
child *DWDie
|
child *DWDie
|
||||||
attr *DWAttr
|
attr *DWAttr
|
||||||
|
// offset into .debug_info section, i.e relative to
|
||||||
|
// infoo. only valid after call to putdie()
|
||||||
offs int64
|
offs int64
|
||||||
hash []*DWDie
|
hash []*DWDie // optional index of children by name, enabled by mkindex()
|
||||||
hlink *DWDie
|
hlink *DWDie // bucket chain in parent's index
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1871,7 +1884,7 @@ func writelines() {
|
||||||
const (
|
const (
|
||||||
CIERESERVE = 16
|
CIERESERVE = 16
|
||||||
DATAALIGNMENTFACTOR = -4
|
DATAALIGNMENTFACTOR = -4
|
||||||
FAKERETURNCOLUMN = 16
|
FAKERETURNCOLUMN = 16 // TODO gdb6 doesn't like > 15?
|
||||||
)
|
)
|
||||||
|
|
||||||
func putpccfadelta(deltapc int64, cfa int64) {
|
func putpccfadelta(deltapc int64, cfa int64) {
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ const (
|
||||||
DW_TAG_variant_part = 0x33
|
DW_TAG_variant_part = 0x33
|
||||||
DW_TAG_variable = 0x34
|
DW_TAG_variable = 0x34
|
||||||
DW_TAG_volatile_type = 0x35
|
DW_TAG_volatile_type = 0x35
|
||||||
|
// Dwarf3
|
||||||
DW_TAG_dwarf_procedure = 0x36
|
DW_TAG_dwarf_procedure = 0x36
|
||||||
DW_TAG_restrict_type = 0x37
|
DW_TAG_restrict_type = 0x37
|
||||||
DW_TAG_interface_type = 0x38
|
DW_TAG_interface_type = 0x38
|
||||||
|
|
@ -99,9 +100,12 @@ const (
|
||||||
DW_TAG_imported_unit = 0x3d
|
DW_TAG_imported_unit = 0x3d
|
||||||
DW_TAG_condition = 0x3f
|
DW_TAG_condition = 0x3f
|
||||||
DW_TAG_shared_type = 0x40
|
DW_TAG_shared_type = 0x40
|
||||||
|
// Dwarf4
|
||||||
DW_TAG_type_unit = 0x41
|
DW_TAG_type_unit = 0x41
|
||||||
DW_TAG_rvalue_reference_type = 0x42
|
DW_TAG_rvalue_reference_type = 0x42
|
||||||
DW_TAG_template_alias = 0x43
|
DW_TAG_template_alias = 0x43
|
||||||
|
|
||||||
|
// User defined
|
||||||
DW_TAG_lo_user = 0x4080
|
DW_TAG_lo_user = 0x4080
|
||||||
DW_TAG_hi_user = 0xffff
|
DW_TAG_hi_user = 0xffff
|
||||||
)
|
)
|
||||||
|
|
@ -118,7 +122,7 @@ const (
|
||||||
DW_CLS_BLOCK
|
DW_CLS_BLOCK
|
||||||
DW_CLS_CONSTANT
|
DW_CLS_CONSTANT
|
||||||
DW_CLS_FLAG
|
DW_CLS_FLAG
|
||||||
DW_CLS_PTR
|
DW_CLS_PTR // lineptr, loclistptr, macptr, rangelistptr
|
||||||
DW_CLS_REFERENCE
|
DW_CLS_REFERENCE
|
||||||
DW_CLS_ADDRLOC
|
DW_CLS_ADDRLOC
|
||||||
DW_CLS_STRING
|
DW_CLS_STRING
|
||||||
|
|
@ -126,185 +130,187 @@ const (
|
||||||
|
|
||||||
// Table 20
|
// Table 20
|
||||||
const (
|
const (
|
||||||
DW_AT_sibling = 0x01
|
DW_AT_sibling = 0x01 // reference
|
||||||
DW_AT_location = 0x02
|
DW_AT_location = 0x02 // block, loclistptr
|
||||||
DW_AT_name = 0x03
|
DW_AT_name = 0x03 // string
|
||||||
DW_AT_ordering = 0x09
|
DW_AT_ordering = 0x09 // constant
|
||||||
DW_AT_byte_size = 0x0b
|
DW_AT_byte_size = 0x0b // block, constant, reference
|
||||||
DW_AT_bit_offset = 0x0c
|
DW_AT_bit_offset = 0x0c // block, constant, reference
|
||||||
DW_AT_bit_size = 0x0d
|
DW_AT_bit_size = 0x0d // block, constant, reference
|
||||||
DW_AT_stmt_list = 0x10
|
DW_AT_stmt_list = 0x10 // lineptr
|
||||||
DW_AT_low_pc = 0x11
|
DW_AT_low_pc = 0x11 // address
|
||||||
DW_AT_high_pc = 0x12
|
DW_AT_high_pc = 0x12 // address
|
||||||
DW_AT_language = 0x13
|
DW_AT_language = 0x13 // constant
|
||||||
DW_AT_discr = 0x15
|
DW_AT_discr = 0x15 // reference
|
||||||
DW_AT_discr_value = 0x16
|
DW_AT_discr_value = 0x16 // constant
|
||||||
DW_AT_visibility = 0x17
|
DW_AT_visibility = 0x17 // constant
|
||||||
DW_AT_import = 0x18
|
DW_AT_import = 0x18 // reference
|
||||||
DW_AT_string_length = 0x19
|
DW_AT_string_length = 0x19 // block, loclistptr
|
||||||
DW_AT_common_reference = 0x1a
|
DW_AT_common_reference = 0x1a // reference
|
||||||
DW_AT_comp_dir = 0x1b
|
DW_AT_comp_dir = 0x1b // string
|
||||||
DW_AT_const_value = 0x1c
|
DW_AT_const_value = 0x1c // block, constant, string
|
||||||
DW_AT_containing_type = 0x1d
|
DW_AT_containing_type = 0x1d // reference
|
||||||
DW_AT_default_value = 0x1e
|
DW_AT_default_value = 0x1e // reference
|
||||||
DW_AT_inline = 0x20
|
DW_AT_inline = 0x20 // constant
|
||||||
DW_AT_is_optional = 0x21
|
DW_AT_is_optional = 0x21 // flag
|
||||||
DW_AT_lower_bound = 0x22
|
DW_AT_lower_bound = 0x22 // block, constant, reference
|
||||||
DW_AT_producer = 0x25
|
DW_AT_producer = 0x25 // string
|
||||||
DW_AT_prototyped = 0x27
|
DW_AT_prototyped = 0x27 // flag
|
||||||
DW_AT_return_addr = 0x2a
|
DW_AT_return_addr = 0x2a // block, loclistptr
|
||||||
DW_AT_start_scope = 0x2c
|
DW_AT_start_scope = 0x2c // constant
|
||||||
DW_AT_bit_stride = 0x2e
|
DW_AT_bit_stride = 0x2e // constant
|
||||||
DW_AT_upper_bound = 0x2f
|
DW_AT_upper_bound = 0x2f // block, constant, reference
|
||||||
DW_AT_abstract_origin = 0x31
|
DW_AT_abstract_origin = 0x31 // reference
|
||||||
DW_AT_accessibility = 0x32
|
DW_AT_accessibility = 0x32 // constant
|
||||||
DW_AT_address_class = 0x33
|
DW_AT_address_class = 0x33 // constant
|
||||||
DW_AT_artificial = 0x34
|
DW_AT_artificial = 0x34 // flag
|
||||||
DW_AT_base_types = 0x35
|
DW_AT_base_types = 0x35 // reference
|
||||||
DW_AT_calling_convention = 0x36
|
DW_AT_calling_convention = 0x36 // constant
|
||||||
DW_AT_count = 0x37
|
DW_AT_count = 0x37 // block, constant, reference
|
||||||
DW_AT_data_member_location = 0x38
|
DW_AT_data_member_location = 0x38 // block, constant, loclistptr
|
||||||
DW_AT_decl_column = 0x39
|
DW_AT_decl_column = 0x39 // constant
|
||||||
DW_AT_decl_file = 0x3a
|
DW_AT_decl_file = 0x3a // constant
|
||||||
DW_AT_decl_line = 0x3b
|
DW_AT_decl_line = 0x3b // constant
|
||||||
DW_AT_declaration = 0x3c
|
DW_AT_declaration = 0x3c // flag
|
||||||
DW_AT_discr_list = 0x3d
|
DW_AT_discr_list = 0x3d // block
|
||||||
DW_AT_encoding = 0x3e
|
DW_AT_encoding = 0x3e // constant
|
||||||
DW_AT_external = 0x3f
|
DW_AT_external = 0x3f // flag
|
||||||
DW_AT_frame_base = 0x40
|
DW_AT_frame_base = 0x40 // block, loclistptr
|
||||||
DW_AT_friend = 0x41
|
DW_AT_friend = 0x41 // reference
|
||||||
DW_AT_identifier_case = 0x42
|
DW_AT_identifier_case = 0x42 // constant
|
||||||
DW_AT_macro_info = 0x43
|
DW_AT_macro_info = 0x43 // macptr
|
||||||
DW_AT_namelist_item = 0x44
|
DW_AT_namelist_item = 0x44 // block
|
||||||
DW_AT_priority = 0x45
|
DW_AT_priority = 0x45 // reference
|
||||||
DW_AT_segment = 0x46
|
DW_AT_segment = 0x46 // block, loclistptr
|
||||||
DW_AT_specification = 0x47
|
DW_AT_specification = 0x47 // reference
|
||||||
DW_AT_static_link = 0x48
|
DW_AT_static_link = 0x48 // block, loclistptr
|
||||||
DW_AT_type = 0x49
|
DW_AT_type = 0x49 // reference
|
||||||
DW_AT_use_location = 0x4a
|
DW_AT_use_location = 0x4a // block, loclistptr
|
||||||
DW_AT_variable_parameter = 0x4b
|
DW_AT_variable_parameter = 0x4b // flag
|
||||||
DW_AT_virtuality = 0x4c
|
DW_AT_virtuality = 0x4c // constant
|
||||||
DW_AT_vtable_elem_location = 0x4d
|
DW_AT_vtable_elem_location = 0x4d // block, loclistptr
|
||||||
DW_AT_allocated = 0x4e
|
// Dwarf3
|
||||||
DW_AT_associated = 0x4f
|
DW_AT_allocated = 0x4e // block, constant, reference
|
||||||
DW_AT_data_location = 0x50
|
DW_AT_associated = 0x4f // block, constant, reference
|
||||||
DW_AT_byte_stride = 0x51
|
DW_AT_data_location = 0x50 // block
|
||||||
DW_AT_entry_pc = 0x52
|
DW_AT_byte_stride = 0x51 // block, constant, reference
|
||||||
DW_AT_use_UTF8 = 0x53
|
DW_AT_entry_pc = 0x52 // address
|
||||||
DW_AT_extension = 0x54
|
DW_AT_use_UTF8 = 0x53 // flag
|
||||||
DW_AT_ranges = 0x55
|
DW_AT_extension = 0x54 // reference
|
||||||
DW_AT_trampoline = 0x56
|
DW_AT_ranges = 0x55 // rangelistptr
|
||||||
DW_AT_call_column = 0x57
|
DW_AT_trampoline = 0x56 // address, flag, reference, string
|
||||||
DW_AT_call_file = 0x58
|
DW_AT_call_column = 0x57 // constant
|
||||||
DW_AT_call_line = 0x59
|
DW_AT_call_file = 0x58 // constant
|
||||||
DW_AT_description = 0x5a
|
DW_AT_call_line = 0x59 // constant
|
||||||
DW_AT_binary_scale = 0x5b
|
DW_AT_description = 0x5a // string
|
||||||
DW_AT_decimal_scale = 0x5c
|
DW_AT_binary_scale = 0x5b // constant
|
||||||
DW_AT_small = 0x5d
|
DW_AT_decimal_scale = 0x5c // constant
|
||||||
DW_AT_decimal_sign = 0x5e
|
DW_AT_small = 0x5d // reference
|
||||||
DW_AT_digit_count = 0x5f
|
DW_AT_decimal_sign = 0x5e // constant
|
||||||
DW_AT_picture_string = 0x60
|
DW_AT_digit_count = 0x5f // constant
|
||||||
DW_AT_mutable = 0x61
|
DW_AT_picture_string = 0x60 // string
|
||||||
DW_AT_threads_scaled = 0x62
|
DW_AT_mutable = 0x61 // flag
|
||||||
DW_AT_explicit = 0x63
|
DW_AT_threads_scaled = 0x62 // flag
|
||||||
DW_AT_object_pointer = 0x64
|
DW_AT_explicit = 0x63 // flag
|
||||||
DW_AT_endianity = 0x65
|
DW_AT_object_pointer = 0x64 // reference
|
||||||
DW_AT_elemental = 0x66
|
DW_AT_endianity = 0x65 // constant
|
||||||
DW_AT_pure = 0x67
|
DW_AT_elemental = 0x66 // flag
|
||||||
DW_AT_recursive = 0x68
|
DW_AT_pure = 0x67 // flag
|
||||||
DW_AT_lo_user = 0x2000
|
DW_AT_recursive = 0x68 // flag
|
||||||
DW_AT_hi_user = 0x3fff
|
|
||||||
|
DW_AT_lo_user = 0x2000 // ---
|
||||||
|
DW_AT_hi_user = 0x3fff // ---
|
||||||
)
|
)
|
||||||
|
|
||||||
// Table 21
|
// Table 21
|
||||||
const (
|
const (
|
||||||
DW_FORM_addr = 0x01
|
DW_FORM_addr = 0x01 // address
|
||||||
DW_FORM_block2 = 0x03
|
DW_FORM_block2 = 0x03 // block
|
||||||
DW_FORM_block4 = 0x04
|
DW_FORM_block4 = 0x04 // block
|
||||||
DW_FORM_data2 = 0x05
|
DW_FORM_data2 = 0x05 // constant
|
||||||
DW_FORM_data4 = 0x06
|
DW_FORM_data4 = 0x06 // constant, lineptr, loclistptr, macptr, rangelistptr
|
||||||
DW_FORM_data8 = 0x07
|
DW_FORM_data8 = 0x07 // constant, lineptr, loclistptr, macptr, rangelistptr
|
||||||
DW_FORM_string = 0x08
|
DW_FORM_string = 0x08 // string
|
||||||
DW_FORM_block = 0x09
|
DW_FORM_block = 0x09 // block
|
||||||
DW_FORM_block1 = 0x0a
|
DW_FORM_block1 = 0x0a // block
|
||||||
DW_FORM_data1 = 0x0b
|
DW_FORM_data1 = 0x0b // constant
|
||||||
DW_FORM_flag = 0x0c
|
DW_FORM_flag = 0x0c // flag
|
||||||
DW_FORM_sdata = 0x0d
|
DW_FORM_sdata = 0x0d // constant
|
||||||
DW_FORM_strp = 0x0e
|
DW_FORM_strp = 0x0e // string
|
||||||
DW_FORM_udata = 0x0f
|
DW_FORM_udata = 0x0f // constant
|
||||||
DW_FORM_ref_addr = 0x10
|
DW_FORM_ref_addr = 0x10 // reference
|
||||||
DW_FORM_ref1 = 0x11
|
DW_FORM_ref1 = 0x11 // reference
|
||||||
DW_FORM_ref2 = 0x12
|
DW_FORM_ref2 = 0x12 // reference
|
||||||
DW_FORM_ref4 = 0x13
|
DW_FORM_ref4 = 0x13 // reference
|
||||||
DW_FORM_ref8 = 0x14
|
DW_FORM_ref8 = 0x14 // reference
|
||||||
DW_FORM_ref_udata = 0x15
|
DW_FORM_ref_udata = 0x15 // reference
|
||||||
DW_FORM_indirect = 0x16
|
DW_FORM_indirect = 0x16 // (see Section 7.5.3)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Table 24 (#operands, notes)
|
// Table 24 (#operands, notes)
|
||||||
const (
|
const (
|
||||||
DW_OP_addr = 0x03
|
DW_OP_addr = 0x03 // 1 constant address (size target specific)
|
||||||
DW_OP_deref = 0x06
|
DW_OP_deref = 0x06 // 0
|
||||||
DW_OP_const1u = 0x08
|
DW_OP_const1u = 0x08 // 1 1-byte constant
|
||||||
DW_OP_const1s = 0x09
|
DW_OP_const1s = 0x09 // 1 1-byte constant
|
||||||
DW_OP_const2u = 0x0a
|
DW_OP_const2u = 0x0a // 1 2-byte constant
|
||||||
DW_OP_const2s = 0x0b
|
DW_OP_const2s = 0x0b // 1 2-byte constant
|
||||||
DW_OP_const4u = 0x0c
|
DW_OP_const4u = 0x0c // 1 4-byte constant
|
||||||
DW_OP_const4s = 0x0d
|
DW_OP_const4s = 0x0d // 1 4-byte constant
|
||||||
DW_OP_const8u = 0x0e
|
DW_OP_const8u = 0x0e // 1 8-byte constant
|
||||||
DW_OP_const8s = 0x0f
|
DW_OP_const8s = 0x0f // 1 8-byte constant
|
||||||
DW_OP_constu = 0x10
|
DW_OP_constu = 0x10 // 1 ULEB128 constant
|
||||||
DW_OP_consts = 0x11
|
DW_OP_consts = 0x11 // 1 SLEB128 constant
|
||||||
DW_OP_dup = 0x12
|
DW_OP_dup = 0x12 // 0
|
||||||
DW_OP_drop = 0x13
|
DW_OP_drop = 0x13 // 0
|
||||||
DW_OP_over = 0x14
|
DW_OP_over = 0x14 // 0
|
||||||
DW_OP_pick = 0x15
|
DW_OP_pick = 0x15 // 1 1-byte stack index
|
||||||
DW_OP_swap = 0x16
|
DW_OP_swap = 0x16 // 0
|
||||||
DW_OP_rot = 0x17
|
DW_OP_rot = 0x17 // 0
|
||||||
DW_OP_xderef = 0x18
|
DW_OP_xderef = 0x18 // 0
|
||||||
DW_OP_abs = 0x19
|
DW_OP_abs = 0x19 // 0
|
||||||
DW_OP_and = 0x1a
|
DW_OP_and = 0x1a // 0
|
||||||
DW_OP_div = 0x1b
|
DW_OP_div = 0x1b // 0
|
||||||
DW_OP_minus = 0x1c
|
DW_OP_minus = 0x1c // 0
|
||||||
DW_OP_mod = 0x1d
|
DW_OP_mod = 0x1d // 0
|
||||||
DW_OP_mul = 0x1e
|
DW_OP_mul = 0x1e // 0
|
||||||
DW_OP_neg = 0x1f
|
DW_OP_neg = 0x1f // 0
|
||||||
DW_OP_not = 0x20
|
DW_OP_not = 0x20 // 0
|
||||||
DW_OP_or = 0x21
|
DW_OP_or = 0x21 // 0
|
||||||
DW_OP_plus = 0x22
|
DW_OP_plus = 0x22 // 0
|
||||||
DW_OP_plus_uconst = 0x23
|
DW_OP_plus_uconst = 0x23 // 1 ULEB128 addend
|
||||||
DW_OP_shl = 0x24
|
DW_OP_shl = 0x24 // 0
|
||||||
DW_OP_shr = 0x25
|
DW_OP_shr = 0x25 // 0
|
||||||
DW_OP_shra = 0x26
|
DW_OP_shra = 0x26 // 0
|
||||||
DW_OP_xor = 0x27
|
DW_OP_xor = 0x27 // 0
|
||||||
DW_OP_skip = 0x2f
|
DW_OP_skip = 0x2f // 1 signed 2-byte constant
|
||||||
DW_OP_bra = 0x28
|
DW_OP_bra = 0x28 // 1 signed 2-byte constant
|
||||||
DW_OP_eq = 0x29
|
DW_OP_eq = 0x29 // 0
|
||||||
DW_OP_ge = 0x2a
|
DW_OP_ge = 0x2a // 0
|
||||||
DW_OP_gt = 0x2b
|
DW_OP_gt = 0x2b // 0
|
||||||
DW_OP_le = 0x2c
|
DW_OP_le = 0x2c // 0
|
||||||
DW_OP_lt = 0x2d
|
DW_OP_lt = 0x2d // 0
|
||||||
DW_OP_ne = 0x2e
|
DW_OP_ne = 0x2e // 0
|
||||||
DW_OP_lit0 = 0x30
|
DW_OP_lit0 = 0x30 // 0 ...
|
||||||
DW_OP_lit31 = 0x4f
|
DW_OP_lit31 = 0x4f // 0 literals 0..31 = (DW_OP_lit0 + literal)
|
||||||
DW_OP_reg0 = 0x50
|
DW_OP_reg0 = 0x50 // 0 ..
|
||||||
DW_OP_reg31 = 0x6f
|
DW_OP_reg31 = 0x6f // 0 reg 0..31 = (DW_OP_reg0 + regnum)
|
||||||
DW_OP_breg0 = 0x70
|
DW_OP_breg0 = 0x70 // 1 ...
|
||||||
DW_OP_breg31 = 0x8f
|
DW_OP_breg31 = 0x8f // 1 SLEB128 offset base register 0..31 = (DW_OP_breg0 + regnum)
|
||||||
DW_OP_regx = 0x90
|
DW_OP_regx = 0x90 // 1 ULEB128 register
|
||||||
DW_OP_fbreg = 0x91
|
DW_OP_fbreg = 0x91 // 1 SLEB128 offset
|
||||||
DW_OP_bregx = 0x92
|
DW_OP_bregx = 0x92 // 2 ULEB128 register followed by SLEB128 offset
|
||||||
DW_OP_piece = 0x93
|
DW_OP_piece = 0x93 // 1 ULEB128 size of piece addressed
|
||||||
DW_OP_deref_size = 0x94
|
DW_OP_deref_size = 0x94 // 1 1-byte size of data retrieved
|
||||||
DW_OP_xderef_size = 0x95
|
DW_OP_xderef_size = 0x95 // 1 1-byte size of data retrieved
|
||||||
DW_OP_nop = 0x96
|
DW_OP_nop = 0x96 // 0
|
||||||
DW_OP_push_object_address = 0x97
|
DW_OP_push_object_address = 0x97 // 0
|
||||||
DW_OP_call2 = 0x98
|
DW_OP_call2 = 0x98 // 1 2-byte offset of DIE
|
||||||
DW_OP_call4 = 0x99
|
DW_OP_call4 = 0x99 // 1 4-byte offset of DIE
|
||||||
DW_OP_call_ref = 0x9a
|
DW_OP_call_ref = 0x9a // 1 4- or 8-byte offset of DIE
|
||||||
DW_OP_form_tls_address = 0x9b
|
DW_OP_form_tls_address = 0x9b // 0
|
||||||
DW_OP_call_frame_cfa = 0x9c
|
DW_OP_call_frame_cfa = 0x9c // 0
|
||||||
DW_OP_bit_piece = 0x9d
|
DW_OP_bit_piece = 0x9d // 2
|
||||||
DW_OP_lo_user = 0xe0
|
DW_OP_lo_user = 0xe0
|
||||||
DW_OP_hi_user = 0xff
|
DW_OP_hi_user = 0xff
|
||||||
)
|
)
|
||||||
|
|
@ -381,6 +387,7 @@ const (
|
||||||
DW_LANG_Fortran90 = 0x0008
|
DW_LANG_Fortran90 = 0x0008
|
||||||
DW_LANG_Pascal83 = 0x0009
|
DW_LANG_Pascal83 = 0x0009
|
||||||
DW_LANG_Modula2 = 0x000a
|
DW_LANG_Modula2 = 0x000a
|
||||||
|
// Dwarf3
|
||||||
DW_LANG_Java = 0x000b
|
DW_LANG_Java = 0x000b
|
||||||
DW_LANG_C99 = 0x000c
|
DW_LANG_C99 = 0x000c
|
||||||
DW_LANG_Ada95 = 0x000d
|
DW_LANG_Ada95 = 0x000d
|
||||||
|
|
@ -390,8 +397,11 @@ const (
|
||||||
DW_LANG_ObjC_plus_plus = 0x0011
|
DW_LANG_ObjC_plus_plus = 0x0011
|
||||||
DW_LANG_UPC = 0x0012
|
DW_LANG_UPC = 0x0012
|
||||||
DW_LANG_D = 0x0013
|
DW_LANG_D = 0x0013
|
||||||
|
// Dwarf4
|
||||||
DW_LANG_Python = 0x0014
|
DW_LANG_Python = 0x0014
|
||||||
|
// Dwarf5
|
||||||
DW_LANG_Go = 0x0016
|
DW_LANG_Go = 0x0016
|
||||||
|
|
||||||
DW_LANG_lo_user = 0x8000
|
DW_LANG_lo_user = 0x8000
|
||||||
DW_LANG_hi_user = 0xffff
|
DW_LANG_hi_user = 0xffff
|
||||||
)
|
)
|
||||||
|
|
@ -444,6 +454,7 @@ const (
|
||||||
DW_LNS_set_basic_block = 0x07
|
DW_LNS_set_basic_block = 0x07
|
||||||
DW_LNS_const_add_pc = 0x08
|
DW_LNS_const_add_pc = 0x08
|
||||||
DW_LNS_fixed_advance_pc = 0x09
|
DW_LNS_fixed_advance_pc = 0x09
|
||||||
|
// Dwarf3
|
||||||
DW_LNS_set_prologue_end = 0x0a
|
DW_LNS_set_prologue_end = 0x0a
|
||||||
DW_LNS_set_epilogue_begin = 0x0b
|
DW_LNS_set_epilogue_begin = 0x0b
|
||||||
DW_LNS_set_isa = 0x0c
|
DW_LNS_set_isa = 0x0c
|
||||||
|
|
@ -469,32 +480,37 @@ const (
|
||||||
|
|
||||||
// Table 40.
|
// Table 40.
|
||||||
const (
|
const (
|
||||||
|
// operand,...
|
||||||
DW_CFA_nop = 0x00
|
DW_CFA_nop = 0x00
|
||||||
DW_CFA_set_loc = 0x01
|
DW_CFA_set_loc = 0x01 // address
|
||||||
DW_CFA_advance_loc1 = 0x02
|
DW_CFA_advance_loc1 = 0x02 // 1-byte delta
|
||||||
DW_CFA_advance_loc2 = 0x03
|
DW_CFA_advance_loc2 = 0x03 // 2-byte delta
|
||||||
DW_CFA_advance_loc4 = 0x04
|
DW_CFA_advance_loc4 = 0x04 // 4-byte delta
|
||||||
DW_CFA_offset_extended = 0x05
|
DW_CFA_offset_extended = 0x05 // ULEB128 register, ULEB128 offset
|
||||||
DW_CFA_restore_extended = 0x06
|
DW_CFA_restore_extended = 0x06 // ULEB128 register
|
||||||
DW_CFA_undefined = 0x07
|
DW_CFA_undefined = 0x07 // ULEB128 register
|
||||||
DW_CFA_same_value = 0x08
|
DW_CFA_same_value = 0x08 // ULEB128 register
|
||||||
DW_CFA_register = 0x09
|
DW_CFA_register = 0x09 // ULEB128 register, ULEB128 register
|
||||||
DW_CFA_remember_state = 0x0a
|
DW_CFA_remember_state = 0x0a
|
||||||
DW_CFA_restore_state = 0x0b
|
DW_CFA_restore_state = 0x0b
|
||||||
DW_CFA_def_cfa = 0x0c
|
|
||||||
DW_CFA_def_cfa_register = 0x0d
|
DW_CFA_def_cfa = 0x0c // ULEB128 register, ULEB128 offset
|
||||||
DW_CFA_def_cfa_offset = 0x0e
|
DW_CFA_def_cfa_register = 0x0d // ULEB128 register
|
||||||
DW_CFA_def_cfa_expression = 0x0f
|
DW_CFA_def_cfa_offset = 0x0e // ULEB128 offset
|
||||||
DW_CFA_expression = 0x10
|
DW_CFA_def_cfa_expression = 0x0f // BLOCK
|
||||||
DW_CFA_offset_extended_sf = 0x11
|
DW_CFA_expression = 0x10 // ULEB128 register, BLOCK
|
||||||
DW_CFA_def_cfa_sf = 0x12
|
DW_CFA_offset_extended_sf = 0x11 // ULEB128 register, SLEB128 offset
|
||||||
DW_CFA_def_cfa_offset_sf = 0x13
|
DW_CFA_def_cfa_sf = 0x12 // ULEB128 register, SLEB128 offset
|
||||||
DW_CFA_val_offset = 0x14
|
DW_CFA_def_cfa_offset_sf = 0x13 // SLEB128 offset
|
||||||
DW_CFA_val_offset_sf = 0x15
|
DW_CFA_val_offset = 0x14 // ULEB128, ULEB128
|
||||||
DW_CFA_val_expression = 0x16
|
DW_CFA_val_offset_sf = 0x15 // ULEB128, SLEB128
|
||||||
|
DW_CFA_val_expression = 0x16 // ULEB128, BLOCK
|
||||||
|
|
||||||
DW_CFA_lo_user = 0x1c
|
DW_CFA_lo_user = 0x1c
|
||||||
DW_CFA_hi_user = 0x3f
|
DW_CFA_hi_user = 0x3f
|
||||||
DW_CFA_advance_loc = 0x1 << 6
|
|
||||||
DW_CFA_offset = 0x2 << 6
|
// Opcodes that take an addend operand.
|
||||||
DW_CFA_restore = 0x3 << 6
|
DW_CFA_advance_loc = 0x1 << 6 // +delta
|
||||||
|
DW_CFA_offset = 0x2 << 6 // +register (ULEB128 offset)
|
||||||
|
DW_CFA_restore = 0x3 << 6 // +register
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -776,6 +776,7 @@ func Elfinit() {
|
||||||
// we use EABI on both linux/arm and freebsd/arm.
|
// we use EABI on both linux/arm and freebsd/arm.
|
||||||
// 32-bit architectures
|
// 32-bit architectures
|
||||||
case '5':
|
case '5':
|
||||||
|
// we use EABI on both linux/arm and freebsd/arm.
|
||||||
if HEADTYPE == Hlinux || HEADTYPE == Hfreebsd {
|
if HEADTYPE == Hlinux || HEADTYPE == Hfreebsd {
|
||||||
ehdr.flags = 0x5000002 // has entry point, Version5 EABI
|
ehdr.flags = 0x5000002 // has entry point, Version5 EABI
|
||||||
}
|
}
|
||||||
|
|
@ -1071,7 +1072,7 @@ const (
|
||||||
ELF_NOTE_NETBSD_NAMESZ = 7
|
ELF_NOTE_NETBSD_NAMESZ = 7
|
||||||
ELF_NOTE_NETBSD_DESCSZ = 4
|
ELF_NOTE_NETBSD_DESCSZ = 4
|
||||||
ELF_NOTE_NETBSD_TAG = 1
|
ELF_NOTE_NETBSD_TAG = 1
|
||||||
ELF_NOTE_NETBSD_VERSION = 599000000
|
ELF_NOTE_NETBSD_VERSION = 599000000 /* NetBSD 5.99 */
|
||||||
)
|
)
|
||||||
|
|
||||||
var ELF_NOTE_NETBSD_NAME = []byte("NetBSD\x00")
|
var ELF_NOTE_NETBSD_NAME = []byte("NetBSD\x00")
|
||||||
|
|
@ -1671,7 +1672,7 @@ func doelf() {
|
||||||
|
|
||||||
Addstring(shstrtab, ".shstrtab")
|
Addstring(shstrtab, ".shstrtab")
|
||||||
|
|
||||||
if Debug['d'] == 0 {
|
if Debug['d'] == 0 { /* -d suppresses dynamic loader format */
|
||||||
Addstring(shstrtab, ".interp")
|
Addstring(shstrtab, ".interp")
|
||||||
Addstring(shstrtab, ".hash")
|
Addstring(shstrtab, ".hash")
|
||||||
Addstring(shstrtab, ".got")
|
Addstring(shstrtab, ".got")
|
||||||
|
|
@ -1919,7 +1920,7 @@ func Asmbelf(symo int64) {
|
||||||
Segtext.Filelen += uint64(o)
|
Segtext.Filelen += uint64(o)
|
||||||
}
|
}
|
||||||
|
|
||||||
if Debug['d'] == 0 {
|
if Debug['d'] == 0 { /* -d suppresses dynamic loader format */
|
||||||
/* interpreter */
|
/* interpreter */
|
||||||
sh := elfshname(".interp")
|
sh := elfshname(".interp")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,8 @@ func expandpkg(t0 string, pkg string) string {
|
||||||
* package import data
|
* package import data
|
||||||
*/
|
*/
|
||||||
type Import struct {
|
type Import struct {
|
||||||
hash *Import
|
hash *Import // next in hash table
|
||||||
prefix string
|
prefix string // "type", "var", "func", "const"
|
||||||
name string
|
name string
|
||||||
def string
|
def string
|
||||||
file string
|
file string
|
||||||
|
|
|
||||||
|
|
@ -265,8 +265,8 @@ type ElfSect struct {
|
||||||
|
|
||||||
type ElfObj struct {
|
type ElfObj struct {
|
||||||
f *Biobuf
|
f *Biobuf
|
||||||
base int64
|
base int64 // offset in f where ELF begins
|
||||||
length int64
|
length int64 // length of ELF
|
||||||
is64 int
|
is64 int
|
||||||
name string
|
name string
|
||||||
e binary.ByteOrder
|
e binary.ByteOrder
|
||||||
|
|
@ -624,7 +624,7 @@ func ldelf(f *Biobuf, pkg string, length int64, pn string) {
|
||||||
}
|
}
|
||||||
sect = &elfobj.sect[sym.shndx:][0]
|
sect = &elfobj.sect[sym.shndx:][0]
|
||||||
if sect.sym == nil {
|
if sect.sym == nil {
|
||||||
if strings.HasPrefix(sym.name, ".Linfo_string") {
|
if strings.HasPrefix(sym.name, ".Linfo_string") { // clang does this
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
Diag("%s: sym#%d: ignoring %s in section %d (type %d)", pn, i, sym.name, sym.shndx, sym.type_)
|
Diag("%s: sym#%d: ignoring %s in section %d (type %d)", pn, i, sym.name, sym.shndx, sym.type_)
|
||||||
|
|
@ -901,7 +901,7 @@ func readelfsym(elfobj *ElfObj, i int, sym *ElfSym, needSym int) (err error) {
|
||||||
|
|
||||||
case ElfSymBindLocal:
|
case ElfSymBindLocal:
|
||||||
if Thearch.Thechar == '5' && (strings.HasPrefix(sym.name, "$a") || strings.HasPrefix(sym.name, "$d")) {
|
if Thearch.Thechar == '5' && (strings.HasPrefix(sym.name, "$a") || strings.HasPrefix(sym.name, "$d")) {
|
||||||
// binutils for arm generate these elfmapping
|
// binutils for arm generate these mapping
|
||||||
// symbols, ignore these
|
// symbols, ignore these
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,8 @@ const (
|
||||||
|
|
||||||
type LdMachoObj struct {
|
type LdMachoObj struct {
|
||||||
f *Biobuf
|
f *Biobuf
|
||||||
base int64
|
base int64 // off in f where Mach-O begins
|
||||||
length int64
|
length int64 // length of Mach-O
|
||||||
is64 bool
|
is64 bool
|
||||||
name string
|
name string
|
||||||
e binary.ByteOrder
|
e binary.ByteOrder
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ const (
|
||||||
IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 16
|
IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 16
|
||||||
IMAGE_SYM_CLASS_REGISTER_PARAM = 17
|
IMAGE_SYM_CLASS_REGISTER_PARAM = 17
|
||||||
IMAGE_SYM_CLASS_BIT_FIELD = 18
|
IMAGE_SYM_CLASS_BIT_FIELD = 18
|
||||||
IMAGE_SYM_CLASS_FAR_EXTERNAL = 68
|
IMAGE_SYM_CLASS_FAR_EXTERNAL = 68 /* Not in PECOFF v8 spec */
|
||||||
IMAGE_SYM_CLASS_BLOCK = 100
|
IMAGE_SYM_CLASS_BLOCK = 100
|
||||||
IMAGE_SYM_CLASS_FUNCTION = 101
|
IMAGE_SYM_CLASS_FUNCTION = 101
|
||||||
IMAGE_SYM_CLASS_END_OF_STRUCT = 102
|
IMAGE_SYM_CLASS_END_OF_STRUCT = 102
|
||||||
|
|
|
||||||
|
|
@ -129,15 +129,15 @@ var Symsize int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MAXIO = 8192
|
MAXIO = 8192
|
||||||
MINFUNC = 16
|
MINFUNC = 16 // minimum size for a function
|
||||||
)
|
)
|
||||||
|
|
||||||
type Segment struct {
|
type Segment struct {
|
||||||
Rwx uint8
|
Rwx uint8 // permission as usual unix bits (5 = r-x etc)
|
||||||
Vaddr uint64
|
Vaddr uint64 // virtual address
|
||||||
Length uint64
|
Length uint64 // length in memory
|
||||||
Fileoff uint64
|
Fileoff uint64 // file offset
|
||||||
Filelen uint64
|
Filelen uint64 // length on disk
|
||||||
Sect *Section
|
Sect *Section
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -253,6 +253,8 @@ var Bso Biobuf
|
||||||
var coutbuf Biobuf
|
var coutbuf Biobuf
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Whether to assume that the external linker is "gold"
|
||||||
|
// (http://sourceware.org/ml/binutils/2008-03/msg00162.html).
|
||||||
AssumeGoldLinker = 0
|
AssumeGoldLinker = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1137,7 +1139,7 @@ var le = Endian{Le16, Le32, Le64}
|
||||||
type Chain struct {
|
type Chain struct {
|
||||||
sym *LSym
|
sym *LSym
|
||||||
up *Chain
|
up *Chain
|
||||||
limit int
|
limit int // limit on entry to sym
|
||||||
}
|
}
|
||||||
|
|
||||||
var morestack *LSym
|
var morestack *LSym
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,14 @@ type IMAGE_EXPORT_DIRECTORY struct {
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PEBASE = 0x00400000
|
PEBASE = 0x00400000
|
||||||
|
|
||||||
|
// SectionAlignment must be greater than or equal to FileAlignment.
|
||||||
|
// The default is the page size for the architecture.
|
||||||
PESECTALIGN = 0x1000
|
PESECTALIGN = 0x1000
|
||||||
|
|
||||||
|
// FileAlignment should be a power of 2 between 512 and 64 K, inclusive.
|
||||||
|
// The default is 512. If the SectionAlignment is less than
|
||||||
|
// the architecture's page size, then FileAlignment must match SectionAlignment.
|
||||||
PEFILEALIGN = 2 << 8
|
PEFILEALIGN = 2 << 8
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -921,7 +928,7 @@ func Asmbpe() {
|
||||||
if pe64 != 0 {
|
if pe64 != 0 {
|
||||||
fh.SizeOfOptionalHeader = uint16(binary.Size(&oh64))
|
fh.SizeOfOptionalHeader = uint16(binary.Size(&oh64))
|
||||||
fh.Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE
|
fh.Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE
|
||||||
oh64.Magic = 0x20b
|
oh64.Magic = 0x20b // PE32+
|
||||||
} else {
|
} else {
|
||||||
fh.SizeOfOptionalHeader = uint16(binary.Size(&oh))
|
fh.SizeOfOptionalHeader = uint16(binary.Size(&oh))
|
||||||
fh.Characteristics |= IMAGE_FILE_32BIT_MACHINE
|
fh.Characteristics |= IMAGE_FILE_32BIT_MACHINE
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
REG_R0 = obj.RBaseARM + iota
|
REG_R0 = obj.RBaseARM + iota // must be 16-aligned
|
||||||
REG_R1
|
REG_R1
|
||||||
REG_R2
|
REG_R2
|
||||||
REG_R3
|
REG_R3
|
||||||
|
|
@ -60,7 +60,8 @@ const (
|
||||||
REG_R13
|
REG_R13
|
||||||
REG_R14
|
REG_R14
|
||||||
REG_R15
|
REG_R15
|
||||||
REG_F0
|
|
||||||
|
REG_F0 // must be 16-aligned
|
||||||
REG_F1
|
REG_F1
|
||||||
REG_F2
|
REG_F2
|
||||||
REG_F3
|
REG_F3
|
||||||
|
|
@ -76,28 +77,37 @@ const (
|
||||||
REG_F13
|
REG_F13
|
||||||
REG_F14
|
REG_F14
|
||||||
REG_F15
|
REG_F15
|
||||||
REG_FPSR
|
|
||||||
|
REG_FPSR // must be 2-aligned
|
||||||
REG_FPCR
|
REG_FPCR
|
||||||
REG_CPSR
|
|
||||||
|
REG_CPSR // must be 2-aligned
|
||||||
REG_SPSR
|
REG_SPSR
|
||||||
|
|
||||||
MAXREG
|
MAXREG
|
||||||
REGRET = REG_R0
|
REGRET = REG_R0
|
||||||
|
/* compiler allocates R1 up as temps */
|
||||||
|
/* compiler allocates register variables R3 up */
|
||||||
|
/* compiler allocates external registers R10 down */
|
||||||
REGEXT = REG_R10
|
REGEXT = REG_R10
|
||||||
|
/* these two registers are declared in runtime.h */
|
||||||
REGG = REGEXT - 0
|
REGG = REGEXT - 0
|
||||||
REGM = REGEXT - 1
|
REGM = REGEXT - 1
|
||||||
|
|
||||||
REGCTXT = REG_R7
|
REGCTXT = REG_R7
|
||||||
REGTMP = REG_R11
|
REGTMP = REG_R11
|
||||||
REGSP = REG_R13
|
REGSP = REG_R13
|
||||||
REGLINK = REG_R14
|
REGLINK = REG_R14
|
||||||
REGPC = REG_R15
|
REGPC = REG_R15
|
||||||
|
|
||||||
NFREG = 16
|
NFREG = 16
|
||||||
|
/* compiler allocates register variables F0 up */
|
||||||
|
/* compiler allocates external registers F7 down */
|
||||||
FREGRET = REG_F0
|
FREGRET = REG_F0
|
||||||
FREGEXT = REG_F7
|
FREGEXT = REG_F7
|
||||||
FREGTMP = REG_F15
|
FREGTMP = REG_F15
|
||||||
)
|
)
|
||||||
|
|
||||||
/* compiler allocates register variables F0 up */
|
|
||||||
/* compiler allocates external registers F7 down */
|
|
||||||
const (
|
const (
|
||||||
C_NONE = iota
|
C_NONE = iota
|
||||||
C_REG
|
C_REG
|
||||||
|
|
@ -108,37 +118,46 @@ const (
|
||||||
C_FREG
|
C_FREG
|
||||||
C_PSR
|
C_PSR
|
||||||
C_FCR
|
C_FCR
|
||||||
C_RCON
|
|
||||||
C_NCON
|
C_RCON /* 0xff rotated */
|
||||||
C_SCON
|
C_NCON /* ~RCON */
|
||||||
|
C_SCON /* 0xffff */
|
||||||
C_LCON
|
C_LCON
|
||||||
C_LCONADDR
|
C_LCONADDR
|
||||||
C_ZFCON
|
C_ZFCON
|
||||||
C_SFCON
|
C_SFCON
|
||||||
C_LFCON
|
C_LFCON
|
||||||
|
|
||||||
C_RACON
|
C_RACON
|
||||||
C_LACON
|
C_LACON
|
||||||
|
|
||||||
C_SBRA
|
C_SBRA
|
||||||
C_LBRA
|
C_LBRA
|
||||||
C_HAUTO
|
|
||||||
C_FAUTO
|
C_HAUTO /* halfword insn offset (-0xff to 0xff) */
|
||||||
C_HFAUTO
|
C_FAUTO /* float insn offset (0 to 0x3fc, word aligned) */
|
||||||
C_SAUTO
|
C_HFAUTO /* both H and F */
|
||||||
|
C_SAUTO /* -0xfff to 0xfff */
|
||||||
C_LAUTO
|
C_LAUTO
|
||||||
|
|
||||||
C_HOREG
|
C_HOREG
|
||||||
C_FOREG
|
C_FOREG
|
||||||
C_HFOREG
|
C_HFOREG
|
||||||
C_SOREG
|
C_SOREG
|
||||||
C_ROREG
|
C_ROREG
|
||||||
C_SROREG
|
C_SROREG /* both nil and R */
|
||||||
C_LOREG
|
C_LOREG
|
||||||
|
|
||||||
C_PC
|
C_PC
|
||||||
C_SP
|
C_SP
|
||||||
C_HREG
|
C_HREG
|
||||||
C_ADDR
|
|
||||||
|
C_ADDR /* reference to relocatable address */
|
||||||
C_TEXTSIZE
|
C_TEXTSIZE
|
||||||
|
|
||||||
C_GOK
|
C_GOK
|
||||||
C_NCLASS
|
|
||||||
|
C_NCLASS /* must be the last */
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -156,7 +175,13 @@ const (
|
||||||
ACMN
|
ACMN
|
||||||
AORR
|
AORR
|
||||||
ABIC
|
ABIC
|
||||||
|
|
||||||
AMVN
|
AMVN
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do not reorder or fragment the conditional branch
|
||||||
|
* opcodes, or the predication code will break
|
||||||
|
*/
|
||||||
ABEQ
|
ABEQ
|
||||||
ABNE
|
ABNE
|
||||||
ABCS
|
ABCS
|
||||||
|
|
@ -173,6 +198,7 @@ const (
|
||||||
ABLT
|
ABLT
|
||||||
ABGT
|
ABGT
|
||||||
ABLE
|
ABLE
|
||||||
|
|
||||||
AMOVWD
|
AMOVWD
|
||||||
AMOVWF
|
AMOVWF
|
||||||
AMOVDW
|
AMOVDW
|
||||||
|
|
@ -181,6 +207,7 @@ const (
|
||||||
AMOVDF
|
AMOVDF
|
||||||
AMOVF
|
AMOVF
|
||||||
AMOVD
|
AMOVD
|
||||||
|
|
||||||
ACMPF
|
ACMPF
|
||||||
ACMPD
|
ACMPD
|
||||||
AADDF
|
AADDF
|
||||||
|
|
@ -195,6 +222,7 @@ const (
|
||||||
ASQRTD
|
ASQRTD
|
||||||
AABSF
|
AABSF
|
||||||
AABSD
|
AABSD
|
||||||
|
|
||||||
ASRL
|
ASRL
|
||||||
ASRA
|
ASRA
|
||||||
ASLL
|
ASLL
|
||||||
|
|
@ -204,6 +232,7 @@ const (
|
||||||
ADIV
|
ADIV
|
||||||
AMOD
|
AMOD
|
||||||
AMODU
|
AMODU
|
||||||
|
|
||||||
AMOVB
|
AMOVB
|
||||||
AMOVBS
|
AMOVBS
|
||||||
AMOVBU
|
AMOVBU
|
||||||
|
|
@ -214,33 +243,46 @@ const (
|
||||||
AMOVM
|
AMOVM
|
||||||
ASWPBU
|
ASWPBU
|
||||||
ASWPW
|
ASWPW
|
||||||
|
|
||||||
ARFE
|
ARFE
|
||||||
ASWI
|
ASWI
|
||||||
AMULA
|
AMULA
|
||||||
|
|
||||||
AWORD
|
AWORD
|
||||||
ABCASE
|
ABCASE
|
||||||
ACASE
|
ACASE
|
||||||
|
|
||||||
AMULL
|
AMULL
|
||||||
AMULAL
|
AMULAL
|
||||||
AMULLU
|
AMULLU
|
||||||
AMULALU
|
AMULALU
|
||||||
|
|
||||||
ABX
|
ABX
|
||||||
ABXRET
|
ABXRET
|
||||||
ADWORD
|
ADWORD
|
||||||
|
|
||||||
ALDREX
|
ALDREX
|
||||||
ASTREX
|
ASTREX
|
||||||
ALDREXD
|
ALDREXD
|
||||||
ASTREXD
|
ASTREXD
|
||||||
|
|
||||||
APLD
|
APLD
|
||||||
|
|
||||||
ACLZ
|
ACLZ
|
||||||
|
|
||||||
AMULWT
|
AMULWT
|
||||||
AMULWB
|
AMULWB
|
||||||
AMULAWT
|
AMULAWT
|
||||||
AMULAWB
|
AMULAWB
|
||||||
|
|
||||||
ADATABUNDLE
|
ADATABUNDLE
|
||||||
ADATABUNDLEEND
|
ADATABUNDLEEND
|
||||||
AMRC
|
|
||||||
|
AMRC // MRC/MCR
|
||||||
|
|
||||||
ALAST
|
ALAST
|
||||||
|
|
||||||
|
// aliases
|
||||||
AB = obj.AJMP
|
AB = obj.AJMP
|
||||||
ABL = obj.ACALL
|
ABL = obj.ACALL
|
||||||
)
|
)
|
||||||
|
|
@ -251,9 +293,14 @@ const (
|
||||||
C_SBIT = 1 << 4
|
C_SBIT = 1 << 4
|
||||||
C_PBIT = 1 << 5
|
C_PBIT = 1 << 5
|
||||||
C_WBIT = 1 << 6
|
C_WBIT = 1 << 6
|
||||||
C_FBIT = 1 << 7
|
C_FBIT = 1 << 7 /* psr flags-only */
|
||||||
C_UBIT = 1 << 7
|
C_UBIT = 1 << 7 /* up bit, unsigned bit */
|
||||||
|
|
||||||
|
// These constants are the ARM condition codes encodings,
|
||||||
|
// XORed with 14 so that C_SCOND_NONE has value 0,
|
||||||
|
// so that a zeroed Prog.scond means "always execute".
|
||||||
C_SCOND_XOR = 14
|
C_SCOND_XOR = 14
|
||||||
|
|
||||||
C_SCOND_EQ = 0 ^ C_SCOND_XOR
|
C_SCOND_EQ = 0 ^ C_SCOND_XOR
|
||||||
C_SCOND_NE = 1 ^ C_SCOND_XOR
|
C_SCOND_NE = 1 ^ C_SCOND_XOR
|
||||||
C_SCOND_HS = 2 ^ C_SCOND_XOR
|
C_SCOND_HS = 2 ^ C_SCOND_XOR
|
||||||
|
|
@ -270,13 +317,10 @@ const (
|
||||||
C_SCOND_LE = 13 ^ C_SCOND_XOR
|
C_SCOND_LE = 13 ^ C_SCOND_XOR
|
||||||
C_SCOND_NONE = 14 ^ C_SCOND_XOR
|
C_SCOND_NONE = 14 ^ C_SCOND_XOR
|
||||||
C_SCOND_NV = 15 ^ C_SCOND_XOR
|
C_SCOND_NV = 15 ^ C_SCOND_XOR
|
||||||
|
|
||||||
|
/* D_SHIFT type */
|
||||||
SHIFT_LL = 0 << 5
|
SHIFT_LL = 0 << 5
|
||||||
SHIFT_LR = 1 << 5
|
SHIFT_LR = 1 << 5
|
||||||
SHIFT_AR = 2 << 5
|
SHIFT_AR = 2 << 5
|
||||||
SHIFT_RR = 3 << 5
|
SHIFT_RR = 3 << 5
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
|
||||||
* this is the ranlib header
|
|
||||||
*/
|
|
||||||
var SYMDEF string
|
|
||||||
|
|
|
||||||
|
|
@ -350,8 +350,8 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3
|
||||||
if out != nil {
|
if out != nil {
|
||||||
out[0] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03c0013f | (uint32(p.To.Reg)&15)<<12 | (uint32(p.To.Reg)&15)<<16 // BIC $0xc000000f, Rx
|
out[0] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03c0013f | (uint32(p.To.Reg)&15)<<12 | (uint32(p.To.Reg)&15)<<16 // BIC $0xc000000f, Rx
|
||||||
if p.As == AB {
|
if p.As == AB {
|
||||||
out[1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff10 | (uint32(p.To.Reg)&15)<<0 // BX Rx // ABL
|
out[1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff10 | (uint32(p.To.Reg)&15)<<0 // BX Rx
|
||||||
} else {
|
} else { // ABL
|
||||||
out[1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff30 | (uint32(p.To.Reg)&15)<<0 // BLX Rx
|
out[1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff30 | (uint32(p.To.Reg)&15)<<0 // BLX Rx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -473,7 +473,8 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.To.Type == obj.TYPE_MEM && p.To.Reg != REG_R13 && p.To.Reg != REG_R9) || (p.From.Type == obj.TYPE_MEM && p.From.Reg != REG_R13 && p.From.Reg != REG_R9) { // MOVW Rx, X(Ry), y != 13 && y != 9 // MOVW X(Rx), Ry, x != 13 && x != 9
|
if (p.To.Type == obj.TYPE_MEM && p.To.Reg != REG_R13 && p.To.Reg != REG_R9) || // MOVW Rx, X(Ry), y != 13 && y != 9
|
||||||
|
(p.From.Type == obj.TYPE_MEM && p.From.Reg != REG_R13 && p.From.Reg != REG_R9) { // MOVW X(Rx), Ry, x != 13 && x != 9
|
||||||
var a *obj.Addr
|
var a *obj.Addr
|
||||||
if p.To.Type == obj.TYPE_MEM {
|
if p.To.Type == obj.TYPE_MEM {
|
||||||
a = &p.To
|
a = &p.To
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,102 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Writing of Go object files.
|
||||||
|
//
|
||||||
|
// Originally, Go object files were Plan 9 object files, but no longer.
|
||||||
|
// Now they are more like standard object files, in that each symbol is defined
|
||||||
|
// by an associated memory image (bytes) and a list of relocations to apply
|
||||||
|
// during linking. We do not (yet?) use a standard file format, however.
|
||||||
|
// For now, the format is chosen to be as simple as possible to read and write.
|
||||||
|
// It may change for reasons of efficiency, or we may even switch to a
|
||||||
|
// standard file format if there are compelling benefits to doing so.
|
||||||
|
// See golang.org/s/go13linker for more background.
|
||||||
|
//
|
||||||
|
// The file format is:
|
||||||
|
//
|
||||||
|
// - magic header: "\x00\x00go13ld"
|
||||||
|
// - byte 1 - version number
|
||||||
|
// - sequence of strings giving dependencies (imported packages)
|
||||||
|
// - empty string (marks end of sequence)
|
||||||
|
// - sequence of defined symbols
|
||||||
|
// - byte 0xff (marks end of sequence)
|
||||||
|
// - magic footer: "\xff\xffgo13ld"
|
||||||
|
//
|
||||||
|
// All integers are stored in a zigzag varint format.
|
||||||
|
// See golang.org/s/go12symtab for a definition.
|
||||||
|
//
|
||||||
|
// Data blocks and strings are both stored as an integer
|
||||||
|
// followed by that many bytes.
|
||||||
|
//
|
||||||
|
// A symbol reference is a string name followed by a version.
|
||||||
|
// An empty name corresponds to a nil LSym* pointer.
|
||||||
|
//
|
||||||
|
// Each symbol is laid out as the following fields (taken from LSym*):
|
||||||
|
//
|
||||||
|
// - byte 0xfe (sanity check for synchronization)
|
||||||
|
// - type [int]
|
||||||
|
// - name [string]
|
||||||
|
// - version [int]
|
||||||
|
// - flags [int]
|
||||||
|
// 1 dupok
|
||||||
|
// - size [int]
|
||||||
|
// - gotype [symbol reference]
|
||||||
|
// - p [data block]
|
||||||
|
// - nr [int]
|
||||||
|
// - r [nr relocations, sorted by off]
|
||||||
|
//
|
||||||
|
// If type == STEXT, there are a few more fields:
|
||||||
|
//
|
||||||
|
// - args [int]
|
||||||
|
// - locals [int]
|
||||||
|
// - nosplit [int]
|
||||||
|
// - flags [int]
|
||||||
|
// 1 leaf
|
||||||
|
// 2 C function
|
||||||
|
// - nlocal [int]
|
||||||
|
// - local [nlocal automatics]
|
||||||
|
// - pcln [pcln table]
|
||||||
|
//
|
||||||
|
// Each relocation has the encoding:
|
||||||
|
//
|
||||||
|
// - off [int]
|
||||||
|
// - siz [int]
|
||||||
|
// - type [int]
|
||||||
|
// - add [int]
|
||||||
|
// - xadd [int]
|
||||||
|
// - sym [symbol reference]
|
||||||
|
// - xsym [symbol reference]
|
||||||
|
//
|
||||||
|
// Each local has the encoding:
|
||||||
|
//
|
||||||
|
// - asym [symbol reference]
|
||||||
|
// - offset [int]
|
||||||
|
// - type [int]
|
||||||
|
// - gotype [symbol reference]
|
||||||
|
//
|
||||||
|
// The pcln table has the encoding:
|
||||||
|
//
|
||||||
|
// - pcsp [data block]
|
||||||
|
// - pcfile [data block]
|
||||||
|
// - pcline [data block]
|
||||||
|
// - npcdata [int]
|
||||||
|
// - pcdata [npcdata data blocks]
|
||||||
|
// - nfuncdata [int]
|
||||||
|
// - funcdata [nfuncdata symbol references]
|
||||||
|
// - funcdatasym [nfuncdata ints]
|
||||||
|
// - nfile [int]
|
||||||
|
// - file [nfile symbol references]
|
||||||
|
//
|
||||||
|
// The file layout and meaning of type integers are architecture-independent.
|
||||||
|
//
|
||||||
|
// TODO(rsc): The file format is good for a first pass but needs work.
|
||||||
|
// - There are SymID in the object file that should really just be strings.
|
||||||
|
// - The actual symbol memory images are interlaced with the symbol
|
||||||
|
// metadata. They should be separated, to reduce the I/O required to
|
||||||
|
// load just the metadata.
|
||||||
|
// - The symbol references should be shortened, either with a symbol
|
||||||
|
// table or by using a simple backward index to an earlier mentioned symbol.
|
||||||
|
|
||||||
package obj
|
package obj
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -39,11 +39,10 @@ import "cmd/internal/obj"
|
||||||
const (
|
const (
|
||||||
NSNAME = 8
|
NSNAME = 8
|
||||||
NSYM = 50
|
NSYM = 50
|
||||||
NREG = 32
|
NREG = 32 /* number of general registers */
|
||||||
NFREG = 32
|
NFREG = 32 /* number of floating point registers */
|
||||||
)
|
)
|
||||||
|
|
||||||
// avoid conflict with ucontext.h. sigh.
|
|
||||||
const (
|
const (
|
||||||
REG_R0 = obj.RBasePPC64 + iota
|
REG_R0 = obj.RBasePPC64 + iota
|
||||||
REG_R1
|
REG_R1
|
||||||
|
|
@ -77,6 +76,7 @@ const (
|
||||||
REG_R29
|
REG_R29
|
||||||
REG_R30
|
REG_R30
|
||||||
REG_R31
|
REG_R31
|
||||||
|
|
||||||
REG_F0 = obj.RBasePPC64 + 32 + iota - 32
|
REG_F0 = obj.RBasePPC64 + 32 + iota - 32
|
||||||
REG_F1
|
REG_F1
|
||||||
REG_F2
|
REG_F2
|
||||||
|
|
@ -109,7 +109,9 @@ const (
|
||||||
REG_F29
|
REG_F29
|
||||||
REG_F30
|
REG_F30
|
||||||
REG_F31
|
REG_F31
|
||||||
|
|
||||||
REG_SPECIAL = obj.RBasePPC64 + 64
|
REG_SPECIAL = obj.RBasePPC64 + 64
|
||||||
|
|
||||||
REG_CR0 = obj.RBasePPC64 + 64 + iota - 65
|
REG_CR0 = obj.RBasePPC64 + 64 + iota - 65
|
||||||
REG_CR1
|
REG_CR1
|
||||||
REG_CR2
|
REG_CR2
|
||||||
|
|
@ -118,37 +120,41 @@ const (
|
||||||
REG_CR5
|
REG_CR5
|
||||||
REG_CR6
|
REG_CR6
|
||||||
REG_CR7
|
REG_CR7
|
||||||
|
|
||||||
REG_MSR = obj.RBasePPC64 + 72 + iota - 73
|
REG_MSR = obj.RBasePPC64 + 72 + iota - 73
|
||||||
REG_FPSCR
|
REG_FPSCR
|
||||||
REG_CR
|
REG_CR
|
||||||
REG_SPR0 = obj.RBasePPC64 + 1024
|
|
||||||
REG_DCR0 = obj.RBasePPC64 + 2048
|
REG_SPR0 = obj.RBasePPC64 + 1024 // first of 1024 registers
|
||||||
|
REG_DCR0 = obj.RBasePPC64 + 2048 // first of 1024 registers
|
||||||
|
|
||||||
REG_XER = REG_SPR0 + 1
|
REG_XER = REG_SPR0 + 1
|
||||||
REG_LR = REG_SPR0 + 8
|
REG_LR = REG_SPR0 + 8
|
||||||
REG_CTR = REG_SPR0 + 9
|
REG_CTR = REG_SPR0 + 9
|
||||||
REGZERO = REG_R0
|
|
||||||
|
REGZERO = REG_R0 /* set to zero */
|
||||||
REGSP = REG_R1
|
REGSP = REG_R1
|
||||||
REGSB = REG_R2
|
REGSB = REG_R2
|
||||||
REGRET = REG_R3
|
REGRET = REG_R3
|
||||||
REGARG = -1
|
REGARG = -1 /* -1 disables passing the first argument in register */
|
||||||
REGRT1 = REG_R3
|
REGRT1 = REG_R3 /* reserved for runtime, duffzero and duffcopy */
|
||||||
REGRT2 = REG_R4
|
REGRT2 = REG_R4 /* reserved for runtime, duffcopy */
|
||||||
REGMIN = REG_R7
|
REGMIN = REG_R7 /* register variables allocated from here to REGMAX */
|
||||||
REGCTXT = REG_R11
|
REGCTXT = REG_R11 /* context for closures */
|
||||||
REGTLS = REG_R13
|
REGTLS = REG_R13 /* C ABI TLS base pointer */
|
||||||
REGMAX = REG_R27
|
REGMAX = REG_R27
|
||||||
REGEXT = REG_R30
|
REGEXT = REG_R30 /* external registers allocated from here down */
|
||||||
REGG = REG_R30
|
REGG = REG_R30 /* G */
|
||||||
REGTMP = REG_R31
|
REGTMP = REG_R31 /* used by the linker */
|
||||||
FREGRET = REG_F0
|
FREGRET = REG_F0
|
||||||
FREGMIN = REG_F17
|
FREGMIN = REG_F17 /* first register variable */
|
||||||
FREGMAX = REG_F26
|
FREGMAX = REG_F26 /* last register variable for 9g only */
|
||||||
FREGEXT = REG_F26
|
FREGEXT = REG_F26 /* first external register */
|
||||||
FREGCVI = REG_F27
|
FREGCVI = REG_F27 /* floating conversion constant */
|
||||||
FREGZERO = REG_F28
|
FREGZERO = REG_F28 /* both float and double */
|
||||||
FREGHALF = REG_F29
|
FREGHALF = REG_F29 /* double */
|
||||||
FREGONE = REG_F30
|
FREGONE = REG_F30 /* double */
|
||||||
FREGTWO = REG_F31
|
FREGTWO = REG_F31 /* double */
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -166,6 +172,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
/* mark flags */
|
||||||
LABEL = 1 << 0
|
LABEL = 1 << 0
|
||||||
LEAF = 1 << 1
|
LEAF = 1 << 1
|
||||||
FLOAT = 1 << 2
|
FLOAT = 1 << 2
|
||||||
|
|
@ -183,19 +190,19 @@ const (
|
||||||
C_REG
|
C_REG
|
||||||
C_FREG
|
C_FREG
|
||||||
C_CREG
|
C_CREG
|
||||||
C_SPR
|
C_SPR /* special processor register */
|
||||||
C_ZCON
|
C_ZCON
|
||||||
C_SCON
|
C_SCON /* 16 bit signed */
|
||||||
C_UCON
|
C_UCON /* 32 bit signed, low 16 bits 0 */
|
||||||
C_ADDCON
|
C_ADDCON /* -0x8000 <= v < 0 */
|
||||||
C_ANDCON
|
C_ANDCON /* 0 < v <= 0xFFFF */
|
||||||
C_LCON
|
C_LCON /* other 32 */
|
||||||
C_DCON
|
C_DCON /* other 64 (could subdivide further) */
|
||||||
C_SACON
|
C_SACON /* $n(REG) where n <= int16 */
|
||||||
C_SECON
|
C_SECON
|
||||||
C_LACON
|
C_LACON /* $n(REG) where int16 < n <= int32 */
|
||||||
C_LECON
|
C_LECON
|
||||||
C_DACON
|
C_DACON /* $n(REG) where int32 < n */
|
||||||
C_SBRA
|
C_SBRA
|
||||||
C_LBRA
|
C_LBRA
|
||||||
C_SAUTO
|
C_SAUTO
|
||||||
|
|
@ -214,7 +221,8 @@ const (
|
||||||
C_GOK
|
C_GOK
|
||||||
C_ADDR
|
C_ADDR
|
||||||
C_TEXTSIZE
|
C_TEXTSIZE
|
||||||
C_NCLASS
|
|
||||||
|
C_NCLASS /* must be the last */
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -414,6 +422,7 @@ const (
|
||||||
ASYNC
|
ASYNC
|
||||||
AXOR
|
AXOR
|
||||||
AXORCC
|
AXORCC
|
||||||
|
|
||||||
ADCBF
|
ADCBF
|
||||||
ADCBI
|
ADCBI
|
||||||
ADCBST
|
ADCBST
|
||||||
|
|
@ -430,9 +439,13 @@ const (
|
||||||
ATLBIEL
|
ATLBIEL
|
||||||
ATLBSYNC
|
ATLBSYNC
|
||||||
ATW
|
ATW
|
||||||
|
|
||||||
ASYSCALL
|
ASYSCALL
|
||||||
AWORD
|
AWORD
|
||||||
|
|
||||||
ARFCI
|
ARFCI
|
||||||
|
|
||||||
|
/* optional on 32-bit */
|
||||||
AFRES
|
AFRES
|
||||||
AFRESCC
|
AFRESCC
|
||||||
AFRSQRTE
|
AFRSQRTE
|
||||||
|
|
@ -443,9 +456,12 @@ const (
|
||||||
AFSQRTCC
|
AFSQRTCC
|
||||||
AFSQRTS
|
AFSQRTS
|
||||||
AFSQRTSCC
|
AFSQRTSCC
|
||||||
|
|
||||||
|
/* 64-bit */
|
||||||
|
|
||||||
ACNTLZD
|
ACNTLZD
|
||||||
ACNTLZDCC
|
ACNTLZDCC
|
||||||
ACMPW
|
ACMPW /* CMP with L=0 */
|
||||||
ACMPWU
|
ACMPWU
|
||||||
ADIVD
|
ADIVD
|
||||||
ADIVDCC
|
ADIVDCC
|
||||||
|
|
@ -457,6 +473,7 @@ const (
|
||||||
ADIVDUV
|
ADIVDUV
|
||||||
AEXTSW
|
AEXTSW
|
||||||
AEXTSWCC
|
AEXTSWCC
|
||||||
|
/* AFCFIW; AFCFIWCC */
|
||||||
AFCFID
|
AFCFID
|
||||||
AFCFIDCC
|
AFCFIDCC
|
||||||
AFCTID
|
AFCTID
|
||||||
|
|
@ -498,6 +515,8 @@ const (
|
||||||
ASRDCC
|
ASRDCC
|
||||||
ASTDCCC
|
ASTDCCC
|
||||||
ATD
|
ATD
|
||||||
|
|
||||||
|
/* 64-bit pseudo operation */
|
||||||
ADWORD
|
ADWORD
|
||||||
AREMD
|
AREMD
|
||||||
AREMDCC
|
AREMDCC
|
||||||
|
|
@ -507,8 +526,13 @@ const (
|
||||||
AREMDUCC
|
AREMDUCC
|
||||||
AREMDUV
|
AREMDUV
|
||||||
AREMDUVCC
|
AREMDUVCC
|
||||||
|
|
||||||
|
/* more 64-bit operations */
|
||||||
AHRFID
|
AHRFID
|
||||||
|
|
||||||
ALAST
|
ALAST
|
||||||
|
|
||||||
|
// aliases
|
||||||
ABR = obj.AJMP
|
ABR = obj.AJMP
|
||||||
ABL = obj.ACALL
|
ABL = obj.ACALL
|
||||||
ARETURN = obj.ARET
|
ARETURN = obj.ARET
|
||||||
|
|
|
||||||
|
|
@ -1331,6 +1331,7 @@ func OP_RLW(op uint32, a uint32, s uint32, sh uint32, mb uint32, me uint32) uint
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
/* each rhs is OPVCC(_, _, _, _) */
|
||||||
OP_ADD = 31<<26 | 266<<1 | 0<<10 | 0
|
OP_ADD = 31<<26 | 266<<1 | 0<<10 | 0
|
||||||
OP_ADDI = 14<<26 | 0<<1 | 0<<10 | 0
|
OP_ADDI = 14<<26 | 0<<1 | 0<<10 | 0
|
||||||
OP_ADDIS = 15<<26 | 0<<1 | 0<<10 | 0
|
OP_ADDIS = 15<<26 | 0<<1 | 0<<10 | 0
|
||||||
|
|
|
||||||
|
|
@ -264,6 +264,7 @@ const (
|
||||||
AXORB
|
AXORB
|
||||||
AXORL
|
AXORL
|
||||||
AXORW
|
AXORW
|
||||||
|
|
||||||
AFMOVB
|
AFMOVB
|
||||||
AFMOVBP
|
AFMOVBP
|
||||||
AFMOVD
|
AFMOVD
|
||||||
|
|
@ -278,6 +279,7 @@ const (
|
||||||
AFMOVWP
|
AFMOVWP
|
||||||
AFMOVX
|
AFMOVX
|
||||||
AFMOVXP
|
AFMOVXP
|
||||||
|
|
||||||
AFCOMB
|
AFCOMB
|
||||||
AFCOMBP
|
AFCOMBP
|
||||||
AFCOMD
|
AFCOMD
|
||||||
|
|
@ -292,38 +294,46 @@ const (
|
||||||
AFUCOM
|
AFUCOM
|
||||||
AFUCOMP
|
AFUCOMP
|
||||||
AFUCOMPP
|
AFUCOMPP
|
||||||
|
|
||||||
AFADDDP
|
AFADDDP
|
||||||
AFADDW
|
AFADDW
|
||||||
AFADDL
|
AFADDL
|
||||||
AFADDF
|
AFADDF
|
||||||
AFADDD
|
AFADDD
|
||||||
|
|
||||||
AFMULDP
|
AFMULDP
|
||||||
AFMULW
|
AFMULW
|
||||||
AFMULL
|
AFMULL
|
||||||
AFMULF
|
AFMULF
|
||||||
AFMULD
|
AFMULD
|
||||||
|
|
||||||
AFSUBDP
|
AFSUBDP
|
||||||
AFSUBW
|
AFSUBW
|
||||||
AFSUBL
|
AFSUBL
|
||||||
AFSUBF
|
AFSUBF
|
||||||
AFSUBD
|
AFSUBD
|
||||||
|
|
||||||
AFSUBRDP
|
AFSUBRDP
|
||||||
AFSUBRW
|
AFSUBRW
|
||||||
AFSUBRL
|
AFSUBRL
|
||||||
AFSUBRF
|
AFSUBRF
|
||||||
AFSUBRD
|
AFSUBRD
|
||||||
|
|
||||||
AFDIVDP
|
AFDIVDP
|
||||||
AFDIVW
|
AFDIVW
|
||||||
AFDIVL
|
AFDIVL
|
||||||
AFDIVF
|
AFDIVF
|
||||||
AFDIVD
|
AFDIVD
|
||||||
|
|
||||||
AFDIVRDP
|
AFDIVRDP
|
||||||
AFDIVRW
|
AFDIVRW
|
||||||
AFDIVRL
|
AFDIVRL
|
||||||
AFDIVRF
|
AFDIVRF
|
||||||
AFDIVRD
|
AFDIVRD
|
||||||
|
|
||||||
AFXCHD
|
AFXCHD
|
||||||
AFFREE
|
AFFREE
|
||||||
|
|
||||||
AFLDCW
|
AFLDCW
|
||||||
AFLDENV
|
AFLDENV
|
||||||
AFRSTOR
|
AFRSTOR
|
||||||
|
|
@ -331,6 +341,7 @@ const (
|
||||||
AFSTCW
|
AFSTCW
|
||||||
AFSTENV
|
AFSTENV
|
||||||
AFSTSW
|
AFSTSW
|
||||||
|
|
||||||
AF2XM1
|
AF2XM1
|
||||||
AFABS
|
AFABS
|
||||||
AFCHS
|
AFCHS
|
||||||
|
|
@ -361,6 +372,8 @@ const (
|
||||||
AFXTRACT
|
AFXTRACT
|
||||||
AFYL2X
|
AFYL2X
|
||||||
AFYL2XP1
|
AFYL2XP1
|
||||||
|
|
||||||
|
// extra 32-bit operations
|
||||||
ACMPXCHGB
|
ACMPXCHGB
|
||||||
ACMPXCHGL
|
ACMPXCHGL
|
||||||
ACMPXCHGW
|
ACMPXCHGW
|
||||||
|
|
@ -382,6 +395,8 @@ const (
|
||||||
AXADDB
|
AXADDB
|
||||||
AXADDL
|
AXADDL
|
||||||
AXADDW
|
AXADDW
|
||||||
|
|
||||||
|
// conditional move
|
||||||
ACMOVLCC
|
ACMOVLCC
|
||||||
ACMOVLCS
|
ACMOVLCS
|
||||||
ACMOVLEQ
|
ACMOVLEQ
|
||||||
|
|
@ -430,6 +445,8 @@ const (
|
||||||
ACMOVWPC
|
ACMOVWPC
|
||||||
ACMOVWPL
|
ACMOVWPL
|
||||||
ACMOVWPS
|
ACMOVWPS
|
||||||
|
|
||||||
|
// 64-bit
|
||||||
AADCQ
|
AADCQ
|
||||||
AADDQ
|
AADDQ
|
||||||
AANDQ
|
AANDQ
|
||||||
|
|
@ -481,6 +498,8 @@ const (
|
||||||
AXADDQ
|
AXADDQ
|
||||||
AXCHGQ
|
AXCHGQ
|
||||||
AXORQ
|
AXORQ
|
||||||
|
|
||||||
|
// media
|
||||||
AADDPD
|
AADDPD
|
||||||
AADDPS
|
AADDPS
|
||||||
AADDSD
|
AADDSD
|
||||||
|
|
@ -682,6 +701,7 @@ const (
|
||||||
AUNPCKLPS
|
AUNPCKLPS
|
||||||
AXORPD
|
AXORPD
|
||||||
AXORPS
|
AXORPS
|
||||||
|
|
||||||
APF2IW
|
APF2IW
|
||||||
APF2IL
|
APF2IL
|
||||||
API2FW
|
API2FW
|
||||||
|
|
@ -690,25 +710,32 @@ const (
|
||||||
ARETFL
|
ARETFL
|
||||||
ARETFQ
|
ARETFQ
|
||||||
ASWAPGS
|
ASWAPGS
|
||||||
|
|
||||||
AMODE
|
AMODE
|
||||||
ACRC32B
|
ACRC32B
|
||||||
ACRC32Q
|
ACRC32Q
|
||||||
AIMUL3Q
|
AIMUL3Q
|
||||||
|
|
||||||
APREFETCHT0
|
APREFETCHT0
|
||||||
APREFETCHT1
|
APREFETCHT1
|
||||||
APREFETCHT2
|
APREFETCHT2
|
||||||
APREFETCHNTA
|
APREFETCHNTA
|
||||||
|
|
||||||
AMOVQL
|
AMOVQL
|
||||||
ABSWAPL
|
ABSWAPL
|
||||||
ABSWAPQ
|
ABSWAPQ
|
||||||
|
|
||||||
AAESENC
|
AAESENC
|
||||||
AAESENCLAST
|
AAESENCLAST
|
||||||
AAESDEC
|
AAESDEC
|
||||||
AAESDECLAST
|
AAESDECLAST
|
||||||
AAESIMC
|
AAESIMC
|
||||||
AAESKEYGENASSIST
|
AAESKEYGENASSIST
|
||||||
|
|
||||||
APSHUFD
|
APSHUFD
|
||||||
APCLMULQDQ
|
APCLMULQDQ
|
||||||
|
|
||||||
|
// from 386
|
||||||
AJCXZW
|
AJCXZW
|
||||||
AFCMOVCC
|
AFCMOVCC
|
||||||
AFCMOVCS
|
AFCMOVCS
|
||||||
|
|
@ -722,6 +749,7 @@ const (
|
||||||
AFCOMIP
|
AFCOMIP
|
||||||
AFUCOMI
|
AFUCOMI
|
||||||
AFUCOMIP
|
AFUCOMIP
|
||||||
|
|
||||||
ALAST
|
ALAST
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -743,6 +771,7 @@ const (
|
||||||
REG_R13B
|
REG_R13B
|
||||||
REG_R14B
|
REG_R14B
|
||||||
REG_R15B
|
REG_R15B
|
||||||
|
|
||||||
REG_AX = obj.RBaseAMD64 + 16 + iota - 17
|
REG_AX = obj.RBaseAMD64 + 16 + iota - 17
|
||||||
REG_CX
|
REG_CX
|
||||||
REG_DX
|
REG_DX
|
||||||
|
|
@ -759,12 +788,16 @@ const (
|
||||||
REG_R13
|
REG_R13
|
||||||
REG_R14
|
REG_R14
|
||||||
REG_R15
|
REG_R15
|
||||||
|
|
||||||
REG_AH = obj.RBaseAMD64 + 32 + iota - 33
|
REG_AH = obj.RBaseAMD64 + 32 + iota - 33
|
||||||
REG_CH
|
REG_CH
|
||||||
REG_DH
|
REG_DH
|
||||||
REG_BH
|
REG_BH
|
||||||
|
|
||||||
REG_F0 = obj.RBaseAMD64 + 36
|
REG_F0 = obj.RBaseAMD64 + 36
|
||||||
|
|
||||||
REG_M0 = obj.RBaseAMD64 + 44
|
REG_M0 = obj.RBaseAMD64 + 44
|
||||||
|
|
||||||
REG_X0 = obj.RBaseAMD64 + 52 + iota - 39
|
REG_X0 = obj.RBaseAMD64 + 52 + iota - 39
|
||||||
REG_X1
|
REG_X1
|
||||||
REG_X2
|
REG_X2
|
||||||
|
|
@ -781,31 +814,37 @@ const (
|
||||||
REG_X13
|
REG_X13
|
||||||
REG_X14
|
REG_X14
|
||||||
REG_X15
|
REG_X15
|
||||||
|
|
||||||
REG_CS = obj.RBaseAMD64 + 68 + iota - 55
|
REG_CS = obj.RBaseAMD64 + 68 + iota - 55
|
||||||
REG_SS
|
REG_SS
|
||||||
REG_DS
|
REG_DS
|
||||||
REG_ES
|
REG_ES
|
||||||
REG_FS
|
REG_FS
|
||||||
REG_GS
|
REG_GS
|
||||||
REG_GDTR
|
|
||||||
REG_IDTR
|
REG_GDTR /* global descriptor table register */
|
||||||
REG_LDTR
|
REG_IDTR /* interrupt descriptor table register */
|
||||||
REG_MSW
|
REG_LDTR /* local descriptor table register */
|
||||||
REG_TASK
|
REG_MSW /* machine status word */
|
||||||
|
REG_TASK /* task register */
|
||||||
|
|
||||||
REG_CR = obj.RBaseAMD64 + 79
|
REG_CR = obj.RBaseAMD64 + 79
|
||||||
REG_DR = obj.RBaseAMD64 + 95
|
REG_DR = obj.RBaseAMD64 + 95
|
||||||
REG_TR = obj.RBaseAMD64 + 103
|
REG_TR = obj.RBaseAMD64 + 103
|
||||||
|
|
||||||
REG_TLS = obj.RBaseAMD64 + 111 + iota - 69
|
REG_TLS = obj.RBaseAMD64 + 111 + iota - 69
|
||||||
|
|
||||||
MAXREG
|
MAXREG
|
||||||
|
|
||||||
REGARG = -1
|
REGARG = -1
|
||||||
REGRET = REG_AX
|
REGRET = REG_AX
|
||||||
FREGRET = REG_X0
|
FREGRET = REG_X0
|
||||||
REGSP = REG_SP
|
REGSP = REG_SP
|
||||||
REGTMP = REG_DI
|
REGTMP = REG_DI
|
||||||
REGCTXT = REG_DX
|
REGCTXT = REG_DX
|
||||||
REGEXT = REG_R15
|
REGEXT = REG_R15 /* compiler allocates external registers R15 down */
|
||||||
FREGMIN = REG_X0 + 5
|
FREGMIN = REG_X0 + 5 /* first register variable */
|
||||||
FREGEXT = REG_X0 + 15
|
FREGEXT = REG_X0 + 15 /* first external register */
|
||||||
T_TYPE = 1 << 0
|
T_TYPE = 1 << 0
|
||||||
T_INDEX = 1 << 1
|
T_INDEX = 1 << 1
|
||||||
T_OFFSET = 1 << 2
|
T_OFFSET = 1 << 2
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,21 @@ import (
|
||||||
// Instruction layout.
|
// Instruction layout.
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MaxAlign = 32
|
MaxAlign = 32 // max data alignment
|
||||||
|
|
||||||
|
// Loop alignment constants:
|
||||||
|
// want to align loop entry to LoopAlign-byte boundary,
|
||||||
|
// and willing to insert at most MaxLoopPad bytes of NOP to do so.
|
||||||
|
// We define a loop entry as the target of a backward jump.
|
||||||
|
//
|
||||||
|
// gcc uses MaxLoopPad = 10 for its 'generic x86-64' config,
|
||||||
|
// and it aligns all jump targets, not just backward jump targets.
|
||||||
|
//
|
||||||
|
// As of 6/1/2012, the effect of setting MaxLoopPad = 10 here
|
||||||
|
// is very slight but negative, so the alignment is disabled by
|
||||||
|
// setting MaxLoopPad = 0. The code is here for reference and
|
||||||
|
// for future experiments.
|
||||||
|
//
|
||||||
LoopAlign = 16
|
LoopAlign = 16
|
||||||
MaxLoopPad = 0
|
MaxLoopPad = 0
|
||||||
FuncAlign = 16
|
FuncAlign = 16
|
||||||
|
|
@ -173,7 +187,7 @@ const (
|
||||||
Zm_r_3d
|
Zm_r_3d
|
||||||
Zm_r_xm_nr
|
Zm_r_xm_nr
|
||||||
Zr_m_xm_nr
|
Zr_m_xm_nr
|
||||||
Zibm_r
|
Zibm_r /* mmx1,mmx2/mem64,imm8 */
|
||||||
Zmb_r
|
Zmb_r
|
||||||
Zaut_r
|
Zaut_r
|
||||||
Zo_m
|
Zo_m
|
||||||
|
|
@ -196,26 +210,28 @@ const (
|
||||||
const (
|
const (
|
||||||
Px = 0
|
Px = 0
|
||||||
Px1 = 1 // symbolic; exact value doesn't matter
|
Px1 = 1 // symbolic; exact value doesn't matter
|
||||||
P32 = 0x32
|
P32 = 0x32 /* 32-bit only */
|
||||||
Pe = 0x66
|
Pe = 0x66 /* operand escape */
|
||||||
Pm = 0x0f
|
Pm = 0x0f /* 2byte opcode escape */
|
||||||
Pq = 0xff
|
Pq = 0xff /* both escapes: 66 0f */
|
||||||
Pb = 0xfe
|
Pb = 0xfe /* byte operands */
|
||||||
Pf2 = 0xf2
|
Pf2 = 0xf2 /* xmm escape 1: f2 0f */
|
||||||
Pf3 = 0xf3
|
Pf3 = 0xf3 /* xmm escape 2: f3 0f */
|
||||||
Pq3 = 0x67
|
Pq3 = 0x67 /* xmm escape 3: 66 48 0f */
|
||||||
Pw = 0x48
|
Pw = 0x48 /* Rex.w */
|
||||||
Pw8 = 0x90 // symbolic; exact value doesn't matter
|
Pw8 = 0x90 // symbolic; exact value doesn't matter
|
||||||
Py = 0x80
|
Py = 0x80 /* defaults to 64-bit mode */
|
||||||
Py1 = 0x81 // symbolic; exact value doesn't matter
|
Py1 = 0x81 // symbolic; exact value doesn't matter
|
||||||
Py3 = 0x83 // symbolic; exact value doesn't matter
|
Py3 = 0x83 // symbolic; exact value doesn't matter
|
||||||
Rxf = 1 << 9
|
|
||||||
Rxt = 1 << 8
|
Rxf = 1 << 9 /* internal flag for Rxr on from */
|
||||||
Rxw = 1 << 3
|
Rxt = 1 << 8 /* internal flag for Rxr on to */
|
||||||
Rxr = 1 << 2
|
Rxw = 1 << 3 /* =1, 64-bit operand size */
|
||||||
Rxx = 1 << 1
|
Rxr = 1 << 2 /* extend modrm reg */
|
||||||
Rxb = 1 << 0
|
Rxx = 1 << 1 /* extend sib index */
|
||||||
Maxand = 10
|
Rxb = 1 << 0 /* extend modrm r/m, sib base, or opcode reg */
|
||||||
|
|
||||||
|
Maxand = 10 /* in -a output width of the byte codes */
|
||||||
)
|
)
|
||||||
|
|
||||||
var ycover [Ymax * Ymax]uint8
|
var ycover [Ymax * Ymax]uint8
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue