Commit cdb7d7dc authored by Russ Cox's avatar Russ Cox

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/6899Reviewed-by: default avatarRob Pike <r@golang.org>
parent d970bea8
......@@ -619,7 +619,7 @@ func asmb() {
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)))
ld.Cseek(int64(dwarfoff))
......
......@@ -67,8 +67,8 @@ const (
PtrSize = 4
IntSize = 4
RegSize = 4
MaxAlign = 8
FuncAlign = 4
MaxAlign = 8 // max data alignment
FuncAlign = 4 // single-instruction alignment
MINLC = 4
)
......
......@@ -134,11 +134,11 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
r.Type = ld.R_ADDR
return
// TODO: What is the difference between all these?
// Handle relocations found in Mach-O object files.
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_BRANCH*2 + 0:
// TODO: What is the difference between all these?
r.Type = ld.R_ADDR
if targ.Type == ld.SDYNIMPORT {
......
// 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
// 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
// THE SOFTWARE.
package main
const (
thechar = '6'
MaxAlign = 32
MaxAlign = 32 // max data alignment
FuncAlign = 16
)
......
......@@ -34,7 +34,7 @@ import "cmd/internal/obj/x86"
import "cmd/internal/gc"
const (
NREGVAR = 16
NREGVAR = 16 /* 8 integer + 8 floating */
)
var regname = []string{
......
// 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
// 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
// THE SOFTWARE.
package main
const (
thechar = '8'
PtrSize = 4
IntSize = 4
RegSize = 4
MaxAlign = 32
MaxAlign = 32 // max data alignment
FuncAlign = 16
MINLC = 1
)
......
// 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.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
// Many Power ISA arithmetic and logical instructions come in four
// standard variants. These bits let us map between variants.
const (
V_CC = 1 << 0
V_V = 1 << 1
V_CC = 1 << 0 // xCC (affect CR field 0 flags)
V_V = 1 << 1 // xV (affect SO and OV flags)
)
......@@ -34,7 +34,7 @@ import "cmd/internal/obj/ppc64"
import "cmd/internal/gc"
const (
NREGVAR = 64
NREGVAR = 64 /* 32 general + 32 floating */
)
var regname = []string{
......
......@@ -66,7 +66,7 @@ const (
PtrSize = 8
IntSize = 8
RegSize = 8
MaxAlign = 32
MaxAlign = 32 // max data alignment
FuncAlign = 8
MINLC = 4
)
......
......@@ -206,15 +206,27 @@ const (
)
type EscState struct {
theSink Node
// Fake node that all
// - return values and output variables
// - parameters on imported functions not marked 'safe'
// - assignments to global variables
// flow to.
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
dsts *NodeList
loopdepth int
pdepth int
dstcount int
edgecount int
noesc *NodeList
recursive bool
dsts *NodeList // all dst nodes
loopdepth int // for detecting nested loop scopes
pdepth int // for debug printing in recursions.
dstcount int // diagnostic
edgecount int // diagnostic
noesc *NodeList // list of possible non-escaping nodes, for printing
recursive bool // recursive function or group of mutually recursive functions.
}
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.
case OAS,
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,
// 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
break
}
// arguments leak out of scope
// TODO: leak to a dummy node instead
fallthrough
// go f(x) - f and x escape
// arguments leak out of scope
// TODO: leak to a dummy node instead
// fallthrough
case OPROC:
// go f(x) - f and x escape
escassign(e, &e.theSink, n.Left.Left)
escassign(e, &e.theSink, n.Left.Right) // ODDDARG for call
......@@ -899,14 +913,15 @@ func escassign(e *EscState, dst *Node, src *Node) {
OSLICEARR,
OSLICE3ARR,
OSLICESTR:
// Conversions, field access, slice all preserve the input value.
escassign(e, dst, src.Left)
// Append returns first argument.
case OAPPEND:
// Append returns first argument.
escassign(e, dst, src.List.N)
// Index of array preserves input value.
case OINDEX:
// Index of array preserves input value.
if Isfixedarray(src.Left.Type) {
escassign(e, dst, src.Left)
}
......
This diff is collapsed.
......@@ -167,6 +167,7 @@ func dumpdata() {
Clearp(Pc)
}
// Fixup instructions after allocauto (formerly compactframe) has moved all autos around.
func fixautoused(p *obj.Prog) {
for lp := &p; ; {
p = *lp
......@@ -258,6 +259,7 @@ func Isfat(t *Type) bool {
return false
}
// Sweep the prog list to mark any used nodes.
func markautoused(p *obj.Prog) {
for ; p != nil; p = p.Link {
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.
type Order struct {
out *NodeList
temp *NodeList
free *NodeList
out *NodeList // list of generated statements
temp *NodeList // head of stack of temporary variables
free *NodeList // free list of NodeList* structs (for use in temp)
}
// Order rewrites fn->nbody to apply the ordering constraints
......
......@@ -2,6 +2,17 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Garbage collector liveness bitmap generation.
// The command line flag -live causes this code to print debug information.
// The levels are:
//
// -live (aka -live=1): print liveness lists as code warnings at safe points
// -live=2: print an assembly listing with liveness annotations
// -live=3: print information during each computation phase (much chattier)
//
// Each level includes the earlier output as well.
package gc
import (
......@@ -34,28 +45,49 @@ const (
// ...
// }
type BasicBlock struct {
pred []*BasicBlock
succ []*BasicBlock
first *obj.Prog
last *obj.Prog
rpo int
mark int
lastbitmapindex int
uevar Bvec
varkill Bvec
livein Bvec
liveout Bvec
avarinit Bvec
avarinitany Bvec
avarinitall Bvec
pred []*BasicBlock // predecessors; if none, probably start of CFG
succ []*BasicBlock // successors; if none, probably ends in return statement
first *obj.Prog // first instruction in block
last *obj.Prog // last instruction in block
rpo int // reverse post-order number (also index in cfg)
mark int // mark bit for traversals
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
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
liveout Bvec
avarinitany Bvec
avarinitall Bvec
}
// A collection of global state used by liveness analysis.
type Liveness struct {
fn *Node
ptxt *obj.Prog
vars []*Node
cfg []*BasicBlock
fn *Node
ptxt *obj.Prog
vars []*Node
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
livepointers []Bvec
}
......
......@@ -79,16 +79,25 @@ const (
)
type Reg struct {
set Bits
use1 Bits
use2 Bits
set Bits // regopt variables written by this instruction.
use1 Bits // regopt variables read by prog->from.
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
refahead Bits
// calahead/calbehind are similar, but for variables in
// instructions that are reachable after hitting at least one
// CALL.
calbehind Bits
calahead Bits
regdiff Bits
act Bits
regu uint64
regdiff Bits
act Bits
regu uint64 // register used bitmap
}
type Rgn struct {
......@@ -639,14 +648,14 @@ func Uniqs(r *Flow) *Flow {
type TempVar struct {
node *Node
def *Flow
use *Flow
freelink *TempVar
merge *TempVar
start int64
end int64
addr uint8
removed uint8
def *Flow // definition of temp var
use *Flow // use list, chained through Flow.data
freelink *TempVar // next free temp in Type.opt list
merge *TempVar // merge var with this one
start int64 // smallest Prog.pc in live range
end int64 // largest Prog.pc in live range
addr uint8 // address taken - no accurate end
removed uint8 // removed from program
}
type startcmp []*TempVar
......
......@@ -135,6 +135,13 @@ out:
}
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
a := n.Right
......
This diff is collapsed.
......@@ -490,7 +490,7 @@ OpSwitch:
case OIND:
ntop := Erv | Etype
if top&Eaddr == 0 {
if top&Eaddr == 0 { // The *x in &*x is not an indirect.
ntop |= Eindir
}
ntop |= top & Ecomplit
......
......@@ -2950,10 +2950,9 @@ func appendslice(n *Node, init **NodeList) *Node {
nif.Ntest = Nod(OGT, nt, Nodintconst(0))
// instantiate growslice(Type*, []any, int) []any
fn := syslook("growslice", 1)
argtype(fn, s.Type.Type)
argtype(fn, s.Type.Type)
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) // 2 ret []any
// s = growslice(T, s, n)
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
w := int(nl.Type.Width * 8)
s := 0
pow := powtwo(nr)
s := 0 // 1 if nr is negative.
pow := powtwo(nr) // if >= 0, nr is 1<<pow
if pow >= 1000 {
// negative power of 2
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))
}
// InterfaceTYpe.methods.length
// InterfaceType.methods.length
func decodetype_ifacemethodcount(s *LSym) int64 {
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
// 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
import (
......@@ -173,10 +183,11 @@ type DWAttrForm struct {
// Go-specific type attributes.
const (
DW_AT_go_kind = 0x2900
DW_AT_go_key = 0x2901
DW_AT_go_elem = 0x2902
DW_AT_internal_location = 253
DW_AT_go_kind = 0x2900
DW_AT_go_key = 0x2901
DW_AT_go_elem = 0x2902
DW_AT_internal_location = 253 // params and locals; not emitted
)
// Index into the abbrevs table below.
......@@ -201,7 +212,7 @@ const (
DW_ABRV_IFACETYPE
DW_ABRV_MAPTYPE
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_STRINGTYPE
DW_ABRV_STRUCTTYPE
......@@ -632,8 +643,8 @@ func dwarfhashstr(s string) uint32 {
type DWAttr struct {
link *DWAttr
atr uint16
cls uint8
atr uint16 // DW_AT_
cls uint8 // DW_CLS_
value int64
data interface{}
}
......@@ -643,9 +654,11 @@ type DWDie struct {
link *DWDie
child *DWDie
attr *DWAttr
offs int64
hash []*DWDie
hlink *DWDie
// offset into .debug_info section, i.e relative to
// infoo. only valid after call to putdie()
offs int64
hash []*DWDie // optional index of children by name, enabled by mkindex()
hlink *DWDie // bucket chain in parent's index
}
/*
......@@ -1871,7 +1884,7 @@ func writelines() {
const (
CIERESERVE = 16
DATAALIGNMENTFACTOR = -4
FAKERETURNCOLUMN = 16
FAKERETURNCOLUMN = 16 // TODO gdb6 doesn't like > 15?
)
func putpccfadelta(deltapc int64, cfa int64) {
......
This diff is collapsed.
......@@ -776,6 +776,7 @@ func Elfinit() {
// we use EABI on both linux/arm and freebsd/arm.
// 32-bit architectures
case '5':
// we use EABI on both linux/arm and freebsd/arm.
if HEADTYPE == Hlinux || HEADTYPE == Hfreebsd {
ehdr.flags = 0x5000002 // has entry point, Version5 EABI
}
......@@ -1071,7 +1072,7 @@ const (
ELF_NOTE_NETBSD_NAMESZ = 7
ELF_NOTE_NETBSD_DESCSZ = 4
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")
......@@ -1671,7 +1672,7 @@ func doelf() {
Addstring(shstrtab, ".shstrtab")
if Debug['d'] == 0 {
if Debug['d'] == 0 { /* -d suppresses dynamic loader format */
Addstring(shstrtab, ".interp")
Addstring(shstrtab, ".hash")
Addstring(shstrtab, ".got")
......@@ -1919,7 +1920,7 @@ func Asmbelf(symo int64) {
Segtext.Filelen += uint64(o)
}
if Debug['d'] == 0 {
if Debug['d'] == 0 { /* -d suppresses dynamic loader format */
/* interpreter */
sh := elfshname(".interp")
......
......@@ -37,8 +37,8 @@ func expandpkg(t0 string, pkg string) string {
* package import data
*/
type Import struct {
hash *Import
prefix string
hash *Import // next in hash table
prefix string // "type", "var", "func", "const"
name string
def string
file string
......
......@@ -265,8 +265,8 @@ type ElfSect struct {
type ElfObj struct {
f *Biobuf
base int64
length int64
base int64 // offset in f where ELF begins
length int64 // length of ELF
is64 int
name string
e binary.ByteOrder
......@@ -624,7 +624,7 @@ func ldelf(f *Biobuf, pkg string, length int64, pn string) {
}
sect = &elfobj.sect[sym.shndx:][0]
if sect.sym == nil {
if strings.HasPrefix(sym.name, ".Linfo_string") {
if strings.HasPrefix(sym.name, ".Linfo_string") { // clang does this
continue
}
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:
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
break
}
......
......@@ -41,8 +41,8 @@ const (
type LdMachoObj struct {
f *Biobuf
base int64
length int64
base int64 // off in f where Mach-O begins
length int64 // length of Mach-O
is64 bool
name string
e binary.ByteOrder
......
......@@ -58,7 +58,7 @@ const (
IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 16
IMAGE_SYM_CLASS_REGISTER_PARAM = 17
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_FUNCTION = 101
IMAGE_SYM_CLASS_END_OF_STRUCT = 102
......
......@@ -129,15 +129,15 @@ var Symsize int32
const (
MAXIO = 8192
MINFUNC = 16
MINFUNC = 16 // minimum size for a function
)
type Segment struct {
Rwx uint8
Vaddr uint64
Length uint64
Fileoff uint64
Filelen uint64
Rwx uint8 // permission as usual unix bits (5 = r-x etc)
Vaddr uint64 // virtual address
Length uint64 // length in memory
Fileoff uint64 // file offset
Filelen uint64 // length on disk
Sect *Section
}
......@@ -253,6 +253,8 @@ var Bso Biobuf
var coutbuf Biobuf
const (
// Whether to assume that the external linker is "gold"
// (http://sourceware.org/ml/binutils/2008-03/msg00162.html).
AssumeGoldLinker = 0
)
......@@ -1137,7 +1139,7 @@ var le = Endian{Le16, Le32, Le64}
type Chain struct {
sym *LSym
up *Chain
limit int
limit int // limit on entry to sym
}
var morestack *LSym
......
......@@ -95,8 +95,15 @@ type IMAGE_EXPORT_DIRECTORY struct {
}
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
// 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
)
......@@ -921,7 +928,7 @@ func Asmbpe() {
if pe64 != 0 {
fh.SizeOfOptionalHeader = uint16(binary.Size(&oh64))
fh.Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE
oh64.Magic = 0x20b
oh64.Magic = 0x20b // PE32+
} else {
fh.SizeOfOptionalHeader = uint16(binary.Size(&oh))
fh.Characteristics |= IMAGE_FILE_32BIT_MACHINE
......
......@@ -44,7 +44,7 @@ const (
)
const (
REG_R0 = obj.RBaseARM + iota
REG_R0 = obj.RBaseARM + iota // must be 16-aligned
REG_R1
REG_R2
REG_R3
......@@ -60,7 +60,8 @@ const (
REG_R13
REG_R14
REG_R15
REG_F0
REG_F0 // must be 16-aligned
REG_F1
REG_F2
REG_F3
......@@ -76,28 +77,37 @@ const (
REG_F13
REG_F14
REG_F15
REG_FPSR
REG_FPSR // must be 2-aligned
REG_FPCR
REG_CPSR
REG_CPSR // must be 2-aligned
REG_SPSR
MAXREG
REGRET = REG_R0
REGEXT = REG_R10
REGG = REGEXT - 0
REGM = REGEXT - 1
REGRET = REG_R0
/* compiler allocates R1 up as temps */
/* compiler allocates register variables R3 up */
/* compiler allocates external registers R10 down */
REGEXT = REG_R10
/* these two registers are declared in runtime.h */
REGG = REGEXT - 0
REGM = REGEXT - 1
REGCTXT = REG_R7
REGTMP = REG_R11
REGSP = REG_R13
REGLINK = REG_R14
REGPC = REG_R15
NFREG = 16
NFREG = 16
/* compiler allocates register variables F0 up */
/* compiler allocates external registers F7 down */
FREGRET = REG_F0
FREGEXT = REG_F7
FREGTMP = REG_F15
)
/* compiler allocates register variables F0 up */
/* compiler allocates external registers F7 down */
const (
C_NONE = iota
C_REG
......@@ -108,37 +118,46 @@ const (
C_FREG
C_PSR
C_FCR
C_RCON
C_NCON
C_SCON
C_RCON /* 0xff rotated */
C_NCON /* ~RCON */
C_SCON /* 0xffff */
C_LCON
C_LCONADDR
C_ZFCON
C_SFCON
C_LFCON
C_RACON
C_LACON
C_SBRA
C_LBRA
C_HAUTO
C_FAUTO
C_HFAUTO
C_SAUTO
C_HAUTO /* halfword insn offset (-0xff to 0xff) */
C_FAUTO /* float insn offset (0 to 0x3fc, word aligned) */
C_HFAUTO /* both H and F */
C_SAUTO /* -0xfff to 0xfff */
C_LAUTO
C_HOREG
C_FOREG
C_HFOREG
C_SOREG
C_ROREG
C_SROREG
C_SROREG /* both nil and R */
C_LOREG
C_PC
C_SP
C_HREG
C_ADDR
C_ADDR /* reference to relocatable address */
C_TEXTSIZE
C_GOK
C_NCLASS
C_NCLASS /* must be the last */
)
const (
......@@ -156,7 +175,13 @@ const (
ACMN
AORR
ABIC
AMVN
/*
* Do not reorder or fragment the conditional branch
* opcodes, or the predication code will break
*/
ABEQ
ABNE
ABCS
......@@ -173,6 +198,7 @@ const (
ABLT
ABGT
ABLE
AMOVWD
AMOVWF
AMOVDW
......@@ -181,6 +207,7 @@ const (
AMOVDF
AMOVF
AMOVD
ACMPF
ACMPD
AADDF
......@@ -195,6 +222,7 @@ const (
ASQRTD
AABSF
AABSD
ASRL
ASRA
ASLL
......@@ -204,6 +232,7 @@ const (
ADIV
AMOD
AMODU
AMOVB
AMOVBS
AMOVBU
......@@ -214,46 +243,64 @@ const (
AMOVM
ASWPBU
ASWPW
ARFE
ASWI
AMULA
AWORD
ABCASE
ACASE
AMULL
AMULAL
AMULLU
AMULALU
ABX
ABXRET
ADWORD
ALDREX
ASTREX
ALDREXD
ASTREXD
APLD
ACLZ
AMULWT
AMULWB
AMULAWT
AMULAWB
ADATABUNDLE
ADATABUNDLEEND
AMRC
AMRC // MRC/MCR
ALAST
// aliases
AB = obj.AJMP
ABL = obj.ACALL
)
/* scond byte */
const (
C_SCOND = (1 << 4) - 1
C_SBIT = 1 << 4
C_PBIT = 1 << 5
C_WBIT = 1 << 6
C_FBIT = 1 << 7
C_UBIT = 1 << 7
C_SCOND_XOR = 14
C_SCOND = (1 << 4) - 1
C_SBIT = 1 << 4
C_PBIT = 1 << 5
C_WBIT = 1 << 6
C_FBIT = 1 << 7 /* psr flags-only */
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_EQ = 0 ^ C_SCOND_XOR
C_SCOND_NE = 1 ^ C_SCOND_XOR
C_SCOND_HS = 2 ^ C_SCOND_XOR
......@@ -270,13 +317,10 @@ const (
C_SCOND_LE = 13 ^ C_SCOND_XOR
C_SCOND_NONE = 14 ^ C_SCOND_XOR
C_SCOND_NV = 15 ^ C_SCOND_XOR
SHIFT_LL = 0 << 5
SHIFT_LR = 1 << 5
SHIFT_AR = 2 << 5
SHIFT_RR = 3 << 5
)
/*
* this is the ranlib header
*/
var SYMDEF string
/* D_SHIFT type */
SHIFT_LL = 0 << 5
SHIFT_LR = 1 << 5
SHIFT_AR = 2 << 5
SHIFT_RR = 3 << 5
)
......@@ -350,8 +350,8 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3
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
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
} else {
out[1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff10 | (uint32(p.To.Reg)&15)<<0 // BX Rx
} else { // ABL
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
}
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
if p.To.Type == obj.TYPE_MEM {
a = &p.To
......
......@@ -2,6 +2,102 @@
// Use of this source code is governed by a BSD-style
// 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
import (
......
......@@ -39,11 +39,10 @@ import "cmd/internal/obj"
const (
NSNAME = 8
NSYM = 50
NREG = 32
NFREG = 32
NREG = 32 /* number of general registers */
NFREG = 32 /* number of floating point registers */
)
// avoid conflict with ucontext.h. sigh.
const (
REG_R0 = obj.RBasePPC64 + iota
REG_R1
......@@ -77,6 +76,7 @@ const (
REG_R29
REG_R30
REG_R31
REG_F0 = obj.RBasePPC64 + 32 + iota - 32
REG_F1
REG_F2
......@@ -109,8 +109,10 @@ const (
REG_F29
REG_F30
REG_F31
REG_SPECIAL = obj.RBasePPC64 + 64
REG_CR0 = obj.RBasePPC64 + 64 + iota - 65
REG_CR0 = obj.RBasePPC64 + 64 + iota - 65
REG_CR1
REG_CR2
REG_CR3
......@@ -118,37 +120,41 @@ const (
REG_CR5
REG_CR6
REG_CR7
REG_MSR = obj.RBasePPC64 + 72 + iota - 73
REG_FPSCR
REG_CR
REG_SPR0 = obj.RBasePPC64 + 1024
REG_DCR0 = obj.RBasePPC64 + 2048
REG_XER = REG_SPR0 + 1
REG_LR = REG_SPR0 + 8
REG_CTR = REG_SPR0 + 9
REGZERO = REG_R0
REG_SPR0 = obj.RBasePPC64 + 1024 // first of 1024 registers
REG_DCR0 = obj.RBasePPC64 + 2048 // first of 1024 registers
REG_XER = REG_SPR0 + 1
REG_LR = REG_SPR0 + 8
REG_CTR = REG_SPR0 + 9
REGZERO = REG_R0 /* set to zero */
REGSP = REG_R1
REGSB = REG_R2
REGRET = REG_R3
REGARG = -1
REGRT1 = REG_R3
REGRT2 = REG_R4
REGMIN = REG_R7
REGCTXT = REG_R11
REGTLS = REG_R13
REGARG = -1 /* -1 disables passing the first argument in register */
REGRT1 = REG_R3 /* reserved for runtime, duffzero and duffcopy */
REGRT2 = REG_R4 /* reserved for runtime, duffcopy */
REGMIN = REG_R7 /* register variables allocated from here to REGMAX */
REGCTXT = REG_R11 /* context for closures */
REGTLS = REG_R13 /* C ABI TLS base pointer */
REGMAX = REG_R27
REGEXT = REG_R30
REGG = REG_R30
REGTMP = REG_R31
REGEXT = REG_R30 /* external registers allocated from here down */
REGG = REG_R30 /* G */
REGTMP = REG_R31 /* used by the linker */
FREGRET = REG_F0
FREGMIN = REG_F17
FREGMAX = REG_F26
FREGEXT = REG_F26
FREGCVI = REG_F27
FREGZERO = REG_F28
FREGHALF = REG_F29
FREGONE = REG_F30
FREGTWO = REG_F31
FREGMIN = REG_F17 /* first register variable */
FREGMAX = REG_F26 /* last register variable for 9g only */
FREGEXT = REG_F26 /* first external register */
FREGCVI = REG_F27 /* floating conversion constant */
FREGZERO = REG_F28 /* both float and double */
FREGHALF = REG_F29 /* double */
FREGONE = REG_F30 /* double */
FREGTWO = REG_F31 /* double */
)
/*
......@@ -166,6 +172,7 @@ const (
)
const (
/* mark flags */
LABEL = 1 << 0
LEAF = 1 << 1
FLOAT = 1 << 2
......@@ -183,19 +190,19 @@ const (
C_REG
C_FREG
C_CREG
C_SPR
C_SPR /* special processor register */
C_ZCON
C_SCON
C_UCON
C_ADDCON
C_ANDCON
C_LCON
C_DCON
C_SACON
C_SCON /* 16 bit signed */
C_UCON /* 32 bit signed, low 16 bits 0 */
C_ADDCON /* -0x8000 <= v < 0 */
C_ANDCON /* 0 < v <= 0xFFFF */
C_LCON /* other 32 */
C_DCON /* other 64 (could subdivide further) */
C_SACON /* $n(REG) where n <= int16 */
C_SECON
C_LACON
C_LACON /* $n(REG) where int16 < n <= int32 */
C_LECON
C_DACON
C_DACON /* $n(REG) where int32 < n */
C_SBRA
C_LBRA
C_SAUTO
......@@ -214,7 +221,8 @@ const (
C_GOK
C_ADDR
C_TEXTSIZE
C_NCLASS
C_NCLASS /* must be the last */
)
const (
......@@ -414,6 +422,7 @@ const (
ASYNC
AXOR
AXORCC
ADCBF
ADCBI
ADCBST
......@@ -430,9 +439,13 @@ const (
ATLBIEL
ATLBSYNC
ATW
ASYSCALL
AWORD
ARFCI
/* optional on 32-bit */
AFRES
AFRESCC
AFRSQRTE
......@@ -443,9 +456,12 @@ const (
AFSQRTCC
AFSQRTS
AFSQRTSCC
/* 64-bit */
ACNTLZD
ACNTLZDCC
ACMPW
ACMPW /* CMP with L=0 */
ACMPWU
ADIVD
ADIVDCC
......@@ -457,6 +473,7 @@ const (
ADIVDUV
AEXTSW
AEXTSWCC
/* AFCFIW; AFCFIWCC */
AFCFID
AFCFIDCC
AFCTID
......@@ -498,6 +515,8 @@ const (
ASRDCC
ASTDCCC
ATD
/* 64-bit pseudo operation */
ADWORD
AREMD
AREMDCC
......@@ -507,8 +526,13 @@ const (
AREMDUCC
AREMDUV
AREMDUVCC
/* more 64-bit operations */
AHRFID
ALAST
// aliases
ABR = obj.AJMP
ABL = obj.ACALL
ARETURN = obj.ARET
......
......@@ -1331,6 +1331,7 @@ func OP_RLW(op uint32, a uint32, s uint32, sh uint32, mb uint32, me uint32) uint
}
const (
/* each rhs is OPVCC(_, _, _, _) */
OP_ADD = 31<<26 | 266<<1 | 0<<10 | 0
OP_ADDI = 14<<26 | 0<<1 | 0<<10 | 0
OP_ADDIS = 15<<26 | 0<<1 | 0<<10 | 0
......
......@@ -264,6 +264,7 @@ const (
AXORB
AXORL
AXORW
AFMOVB
AFMOVBP
AFMOVD
......@@ -278,6 +279,7 @@ const (
AFMOVWP
AFMOVX
AFMOVXP
AFCOMB
AFCOMBP
AFCOMD
......@@ -292,38 +294,46 @@ const (
AFUCOM
AFUCOMP
AFUCOMPP
AFADDDP
AFADDW
AFADDL
AFADDF
AFADDD
AFMULDP
AFMULW
AFMULL
AFMULF
AFMULD
AFSUBDP
AFSUBW
AFSUBL
AFSUBF
AFSUBD
AFSUBRDP
AFSUBRW
AFSUBRL
AFSUBRF
AFSUBRD
AFDIVDP
AFDIVW
AFDIVL
AFDIVF
AFDIVD
AFDIVRDP
AFDIVRW
AFDIVRL
AFDIVRF
AFDIVRD
AFXCHD
AFFREE
AFLDCW
AFLDENV
AFRSTOR
......@@ -331,6 +341,7 @@ const (
AFSTCW
AFSTENV
AFSTSW
AF2XM1
AFABS
AFCHS
......@@ -361,6 +372,8 @@ const (
AFXTRACT
AFYL2X
AFYL2XP1
// extra 32-bit operations
ACMPXCHGB
ACMPXCHGL
ACMPXCHGW
......@@ -382,6 +395,8 @@ const (
AXADDB
AXADDL
AXADDW
// conditional move
ACMOVLCC
ACMOVLCS
ACMOVLEQ
......@@ -430,6 +445,8 @@ const (
ACMOVWPC
ACMOVWPL
ACMOVWPS
// 64-bit
AADCQ
AADDQ
AANDQ
......@@ -481,6 +498,8 @@ const (
AXADDQ
AXCHGQ
AXORQ
// media
AADDPD
AADDPS
AADDSD
......@@ -682,6 +701,7 @@ const (
AUNPCKLPS
AXORPD
AXORPS
APF2IW
APF2IL
API2FW
......@@ -690,25 +710,32 @@ const (
ARETFL
ARETFQ
ASWAPGS
AMODE
ACRC32B
ACRC32Q
AIMUL3Q
APREFETCHT0
APREFETCHT1
APREFETCHT2
APREFETCHNTA
AMOVQL
ABSWAPL
ABSWAPQ
AAESENC
AAESENCLAST
AAESDEC
AAESDECLAST
AAESIMC
AAESKEYGENASSIST
APSHUFD
APCLMULQDQ
// from 386
AJCXZW
AFCMOVCC
AFCMOVCS
......@@ -722,6 +749,7 @@ const (
AFCOMIP
AFUCOMI
AFUCOMIP
ALAST
)
......@@ -743,6 +771,7 @@ const (
REG_R13B
REG_R14B
REG_R15B
REG_AX = obj.RBaseAMD64 + 16 + iota - 17
REG_CX
REG_DX
......@@ -759,12 +788,16 @@ const (
REG_R13
REG_R14
REG_R15
REG_AH = obj.RBaseAMD64 + 32 + iota - 33
REG_CH
REG_DH
REG_BH
REG_F0 = obj.RBaseAMD64 + 36
REG_M0 = obj.RBaseAMD64 + 44
REG_X0 = obj.RBaseAMD64 + 52 + iota - 39
REG_X1
REG_X2
......@@ -781,31 +814,37 @@ const (
REG_X13
REG_X14
REG_X15
REG_CS = obj.RBaseAMD64 + 68 + iota - 55
REG_SS
REG_DS
REG_ES
REG_FS
REG_GS
REG_GDTR
REG_IDTR
REG_LDTR
REG_MSW
REG_TASK
REG_CR = obj.RBaseAMD64 + 79
REG_DR = obj.RBaseAMD64 + 95
REG_TR = obj.RBaseAMD64 + 103
REG_GDTR /* global descriptor table register */
REG_IDTR /* interrupt descriptor table register */
REG_LDTR /* local descriptor table register */
REG_MSW /* machine status word */
REG_TASK /* task register */
REG_CR = obj.RBaseAMD64 + 79
REG_DR = obj.RBaseAMD64 + 95
REG_TR = obj.RBaseAMD64 + 103
REG_TLS = obj.RBaseAMD64 + 111 + iota - 69
MAXREG
REGARG = -1
REGRET = REG_AX
FREGRET = REG_X0
REGSP = REG_SP
REGTMP = REG_DI
REGCTXT = REG_DX
REGEXT = REG_R15
FREGMIN = REG_X0 + 5
FREGEXT = REG_X0 + 15
REGEXT = REG_R15 /* compiler allocates external registers R15 down */
FREGMIN = REG_X0 + 5 /* first register variable */
FREGEXT = REG_X0 + 15 /* first external register */
T_TYPE = 1 << 0
T_INDEX = 1 << 1
T_OFFSET = 1 << 2
......
......@@ -40,7 +40,21 @@ import (
// Instruction layout.
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
MaxLoopPad = 0
FuncAlign = 16
......@@ -173,7 +187,7 @@ const (
Zm_r_3d
Zm_r_xm_nr
Zr_m_xm_nr
Zibm_r
Zibm_r /* mmx1,mmx2/mem64,imm8 */
Zmb_r
Zaut_r
Zo_m
......@@ -194,28 +208,30 @@ const (
)
const (
Px = 0
Px1 = 1 // symbolic; exact value doesn't matter
P32 = 0x32
Pe = 0x66
Pm = 0x0f
Pq = 0xff
Pb = 0xfe
Pf2 = 0xf2
Pf3 = 0xf3
Pq3 = 0x67
Pw = 0x48
Pw8 = 0x90 // symbolic; exact value doesn't matter
Py = 0x80
Py1 = 0x81 // symbolic; exact value doesn't matter
Py3 = 0x83 // symbolic; exact value doesn't matter
Rxf = 1 << 9
Rxt = 1 << 8
Rxw = 1 << 3
Rxr = 1 << 2
Rxx = 1 << 1
Rxb = 1 << 0
Maxand = 10
Px = 0
Px1 = 1 // symbolic; exact value doesn't matter
P32 = 0x32 /* 32-bit only */
Pe = 0x66 /* operand escape */
Pm = 0x0f /* 2byte opcode escape */
Pq = 0xff /* both escapes: 66 0f */
Pb = 0xfe /* byte operands */
Pf2 = 0xf2 /* xmm escape 1: f2 0f */
Pf3 = 0xf3 /* xmm escape 2: f3 0f */
Pq3 = 0x67 /* xmm escape 3: 66 48 0f */
Pw = 0x48 /* Rex.w */
Pw8 = 0x90 // symbolic; exact value doesn't matter
Py = 0x80 /* defaults to 64-bit mode */
Py1 = 0x81 // symbolic; exact value doesn't matter
Py3 = 0x83 // symbolic; exact value doesn't matter
Rxf = 1 << 9 /* internal flag for Rxr on from */
Rxt = 1 << 8 /* internal flag for Rxr on to */
Rxw = 1 << 3 /* =1, 64-bit operand size */
Rxr = 1 << 2 /* extend modrm reg */
Rxx = 1 << 1 /* extend sib index */
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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment