Commit 8c195bdf authored by Russ Cox's avatar Russ Cox

[dev.cc] cmd/internal/gc, cmd/new6g etc: convert from cmd/gc, cmd/6g etc

First draft of converted Go compiler, using rsc.io/c2go rev 83d795a.

Change-Id: I29f4c7010de07d2ff1947bbca9865879d83c32c3
Reviewed-on: https://go-review.googlesource.com/4851Reviewed-by: default avatarRob Pike <r@golang.org>
parent c11882bc
This diff is collapsed.
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gc
const (
DEFAULTCAPACITY = 16
)
// Inferno utils/cc/bits.c
// http://code.google.com/p/inferno-os/source/browse/utils/cc/bits.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 gc
import "fmt"
/*
Bits
bor(Bits a, Bits b)
{
Bits c;
int i;
for(i=0; i<BITS; i++)
c.b[i] = a.b[i] | b.b[i];
return c;
}
Bits
band(Bits a, Bits b)
{
Bits c;
int i;
for(i=0; i<BITS; i++)
c.b[i] = a.b[i] & b.b[i];
return c;
}
Bits
bnot(Bits a)
{
Bits c;
int i;
for(i=0; i<BITS; i++)
c.b[i] = ~a.b[i];
return c;
}
*/
func bany(a *Bits) int {
var i int
for i = 0; i < BITS; i++ {
if a.b[i] != 0 {
return 1
}
}
return 0
}
/*
int
beq(Bits a, Bits b)
{
int i;
for(i=0; i<BITS; i++)
if(a.b[i] != b.b[i])
return 0;
return 1;
}
*/
func bnum(a Bits) int {
var i int
var b uint64
for i = 0; i < BITS; i++ {
b = a.b[i]
if b != 0 {
return 64*i + Bitno(b)
}
}
Fatal("bad in bnum")
return 0
}
func blsh(n uint) Bits {
var c Bits
c = zbits
c.b[n/64] = 1 << (n % 64)
return c
}
func btest(a *Bits, n uint) int {
return bool2int(a.b[n/64]&(1<<(n%64)) != 0)
}
func biset(a *Bits, n uint) {
a.b[n/64] |= 1 << (n % 64)
}
func biclr(a *Bits, n uint) {
a.b[n/64] &^= (1 << (n % 64))
}
func Bitno(b uint64) int {
var i int
for i = 0; i < 64; i++ {
if b&(1<<uint(i)) != 0 {
return i
}
}
Fatal("bad in bitno")
return 0
}
func Qconv(bits Bits, flag int) string {
var fp string
var i int
var first int
first = 1
for bany(&bits) != 0 {
i = bnum(bits)
if first != 0 {
first = 0
} else {
fp += fmt.Sprintf(" ")
}
if var_[i].node == nil || var_[i].node.Sym == nil {
fp += fmt.Sprintf("$%d", i)
} else {
fp += fmt.Sprintf("%s(%d)", var_[i].node.Sym.Name, i)
if var_[i].offset != 0 {
fp += fmt.Sprintf("%+d", int64(var_[i].offset))
}
}
biclr(&bits, uint(i))
}
return fp
}
This diff is collapsed.
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gc
import "fmt"
const (
WORDSIZE = 4
WORDBITS = 32
WORDMASK = WORDBITS - 1
WORDSHIFT = 5
)
func bvsize(n uint32) uint32 {
return ((n + WORDBITS - 1) / WORDBITS) * WORDSIZE
}
func bvbits(bv *Bvec) int32 {
return bv.n
}
func bvwords(bv *Bvec) int32 {
return (bv.n + WORDBITS - 1) / WORDBITS
}
func bvalloc(n int32) *Bvec {
return &Bvec{n, make([]uint32, bvsize(uint32(n))/4)}
}
/* difference */
func bvandnot(dst *Bvec, src1 *Bvec, src2 *Bvec) {
var i int32
var w int32
if dst.n != src1.n || dst.n != src2.n {
Fatal("bvand: lengths %d, %d, and %d are not equal", dst.n, src1.n, src2.n)
}
i = 0
w = 0
for ; i < dst.n; (func() { i += WORDBITS; w++ })() {
dst.b[w] = src1.b[w] &^ src2.b[w]
}
}
func bvcmp(bv1 *Bvec, bv2 *Bvec) int {
if bv1.n != bv2.n {
Fatal("bvequal: lengths %d and %d are not equal", bv1.n, bv2.n)
}
for i, x := range bv1.b {
if x != bv2.b[i] {
return 1
}
}
return 0
}
func bvcopy(dst *Bvec, src *Bvec) {
for i, x := range src.b {
dst.b[i] = x
}
}
func bvconcat(src1 *Bvec, src2 *Bvec) *Bvec {
var dst *Bvec
var i int32
dst = bvalloc(src1.n + src2.n)
for i = 0; i < src1.n; i++ {
if bvget(src1, i) != 0 {
bvset(dst, i)
}
}
for i = 0; i < src2.n; i++ {
if bvget(src2, i) != 0 {
bvset(dst, i+src1.n)
}
}
return dst
}
func bvget(bv *Bvec, i int32) int {
if i < 0 || i >= bv.n {
Fatal("bvget: index %d is out of bounds with length %d\n", i, bv.n)
}
return int((bv.b[i>>WORDSHIFT] >> uint(i&WORDMASK)) & 1)
}
// bvnext returns the smallest index >= i for which bvget(bv, i) == 1.
// If there is no such index, bvnext returns -1.
func bvnext(bv *Bvec, i int32) int {
var w uint32
if i >= bv.n {
return -1
}
// Jump i ahead to next word with bits.
if bv.b[i>>WORDSHIFT]>>uint(i&WORDMASK) == 0 {
i &^= WORDMASK
i += WORDBITS
for i < bv.n && bv.b[i>>WORDSHIFT] == 0 {
i += WORDBITS
}
}
if i >= bv.n {
return -1
}
// Find 1 bit.
w = bv.b[i>>WORDSHIFT] >> uint(i&WORDMASK)
for w&1 == 0 {
w >>= 1
i++
}
return int(i)
}
func bvisempty(bv *Bvec) int {
var i int32
for i = 0; i < bv.n; i += WORDBITS {
if bv.b[i>>WORDSHIFT] != 0 {
return 0
}
}
return 1
}
func bvnot(bv *Bvec) {
var i int32
var w int32
i = 0
w = 0
for ; i < bv.n; (func() { i += WORDBITS; w++ })() {
bv.b[w] = ^bv.b[w]
}
}
/* union */
func bvor(dst *Bvec, src1 *Bvec, src2 *Bvec) {
var i int32
var w int32
if dst.n != src1.n || dst.n != src2.n {
Fatal("bvor: lengths %d, %d, and %d are not equal", dst.n, src1.n, src2.n)
}
i = 0
w = 0
for ; i < dst.n; (func() { i += WORDBITS; w++ })() {
dst.b[w] = src1.b[w] | src2.b[w]
}
}
/* intersection */
func bvand(dst *Bvec, src1 *Bvec, src2 *Bvec) {
var i int32
var w int32
if dst.n != src1.n || dst.n != src2.n {
Fatal("bvor: lengths %d, %d, and %d are not equal", dst.n, src1.n, src2.n)
}
i = 0
w = 0
for ; i < dst.n; (func() { i += WORDBITS; w++ })() {
dst.b[w] = src1.b[w] & src2.b[w]
}
}
func bvprint(bv *Bvec) {
var i int32
fmt.Printf("#*")
for i = 0; i < bv.n; i++ {
fmt.Printf("%d", bvget(bv, i))
}
}
func bvreset(bv *Bvec, i int32) {
var mask uint32
if i < 0 || i >= bv.n {
Fatal("bvreset: index %d is out of bounds with length %d\n", i, bv.n)
}
mask = ^(1 << uint(i%WORDBITS))
bv.b[i/WORDBITS] &= mask
}
func bvresetall(bv *Bvec) {
for i := range bv.b {
bv.b[i] = 0
}
}
func bvset(bv *Bvec, i int32) {
var mask uint32
if i < 0 || i >= bv.n {
Fatal("bvset: index %d is out of bounds with length %d\n", i, bv.n)
}
mask = 1 << uint(i%WORDBITS)
bv.b[i/WORDBITS] |= mask
}
This diff is collapsed.
This diff is collapsed.
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gc
import "cmd/internal/obj"
func CASE(a int, b int) int {
return a<<16 | b
}
func overlap_cplx(f *Node, t *Node) int {
// check whether f and t could be overlapping stack references.
// not exact, because it's hard to check for the stack register
// in portable code. close enough: worst case we will allocate
// an extra temporary and the registerizer will clean it up.
return bool2int(f.Op == OINDREG && t.Op == OINDREG && f.Xoffset+f.Type.Width >= t.Xoffset && t.Xoffset+t.Type.Width >= f.Xoffset)
}
func Complexbool(op int, nl *Node, nr *Node, true_ bool, likely int, to *obj.Prog) {
var tnl Node
var tnr Node
var n1 Node
var n2 Node
var n3 Node
var n4 Node
var na Node
var nb Node
var nc Node
// make both sides addable in ullman order
if nr != nil {
if nl.Ullman > nr.Ullman && !(nl.Addable != 0) {
Tempname(&tnl, nl.Type)
Thearch.Cgen(nl, &tnl)
nl = &tnl
}
if !(nr.Addable != 0) {
Tempname(&tnr, nr.Type)
Thearch.Cgen(nr, &tnr)
nr = &tnr
}
}
if !(nl.Addable != 0) {
Tempname(&tnl, nl.Type)
Thearch.Cgen(nl, &tnl)
nl = &tnl
}
// build tree
// real(l) == real(r) && imag(l) == imag(r)
subnode(&n1, &n2, nl)
subnode(&n3, &n4, nr)
na = Node{}
na.Op = OANDAND
na.Left = &nb
na.Right = &nc
na.Type = Types[TBOOL]
nb = Node{}
nb.Op = OEQ
nb.Left = &n1
nb.Right = &n3
nb.Type = Types[TBOOL]
nc = Node{}
nc.Op = OEQ
nc.Left = &n2
nc.Right = &n4
nc.Type = Types[TBOOL]
if op == ONE {
true_ = !true_
}
Thearch.Bgen(&na, true_, likely, to)
}
// break addable nc-complex into nr-real and ni-imaginary
func subnode(nr *Node, ni *Node, nc *Node) {
var tc int
var t *Type
if !(nc.Addable != 0) {
Fatal("subnode not addable")
}
tc = Simsimtype(nc.Type)
tc = cplxsubtype(tc)
t = Types[tc]
if nc.Op == OLITERAL {
nodfconst(nr, t, &nc.Val.U.Cval.Real)
nodfconst(ni, t, &nc.Val.U.Cval.Imag)
return
}
*nr = *nc
nr.Type = t
*ni = *nc
ni.Type = t
ni.Xoffset += t.Width
}
// generate code res = -nl
func minus(nl *Node, res *Node) {
var ra Node
ra = Node{}
ra.Op = OMINUS
ra.Left = nl
ra.Type = nl.Type
Thearch.Cgen(&ra, res)
}
// build and execute tree
// real(res) = -real(nl)
// imag(res) = -imag(nl)
func complexminus(nl *Node, res *Node) {
var n1 Node
var n2 Node
var n5 Node
var n6 Node
subnode(&n1, &n2, nl)
subnode(&n5, &n6, res)
minus(&n1, &n5)
minus(&n2, &n6)
}
// build and execute tree
// real(res) = real(nl) op real(nr)
// imag(res) = imag(nl) op imag(nr)
func complexadd(op int, nl *Node, nr *Node, res *Node) {
var n1 Node
var n2 Node
var n3 Node
var n4 Node
var n5 Node
var n6 Node
var ra Node
subnode(&n1, &n2, nl)
subnode(&n3, &n4, nr)
subnode(&n5, &n6, res)
ra = Node{}
ra.Op = uint8(op)
ra.Left = &n1
ra.Right = &n3
ra.Type = n1.Type
Thearch.Cgen(&ra, &n5)
ra = Node{}
ra.Op = uint8(op)
ra.Left = &n2
ra.Right = &n4
ra.Type = n2.Type
Thearch.Cgen(&ra, &n6)
}
// build and execute tree
// tmp = real(nl)*real(nr) - imag(nl)*imag(nr)
// imag(res) = real(nl)*imag(nr) + imag(nl)*real(nr)
// real(res) = tmp
func complexmul(nl *Node, nr *Node, res *Node) {
var n1 Node
var n2 Node
var n3 Node
var n4 Node
var n5 Node
var n6 Node
var rm1 Node
var rm2 Node
var ra Node
var tmp Node
subnode(&n1, &n2, nl)
subnode(&n3, &n4, nr)
subnode(&n5, &n6, res)
Tempname(&tmp, n5.Type)
// real part -> tmp
rm1 = Node{}
rm1.Op = OMUL
rm1.Left = &n1
rm1.Right = &n3
rm1.Type = n1.Type
rm2 = Node{}
rm2.Op = OMUL
rm2.Left = &n2
rm2.Right = &n4
rm2.Type = n2.Type
ra = Node{}
ra.Op = OSUB
ra.Left = &rm1
ra.Right = &rm2
ra.Type = rm1.Type
Thearch.Cgen(&ra, &tmp)
// imag part
rm1 = Node{}
rm1.Op = OMUL
rm1.Left = &n1
rm1.Right = &n4
rm1.Type = n1.Type
rm2 = Node{}
rm2.Op = OMUL
rm2.Left = &n2
rm2.Right = &n3
rm2.Type = n2.Type
ra = Node{}
ra.Op = OADD
ra.Left = &rm1
ra.Right = &rm2
ra.Type = rm1.Type
Thearch.Cgen(&ra, &n6)
// tmp ->real part
Thearch.Cgen(&tmp, &n5)
}
func nodfconst(n *Node, t *Type, fval *Mpflt) {
*n = Node{}
n.Op = OLITERAL
n.Addable = 1
ullmancalc(n)
n.Val.U.Fval = fval
n.Val.Ctype = CTFLT
n.Type = t
if !(Isfloat[t.Etype] != 0) {
Fatal("nodfconst: bad type %v", Tconv(t, 0))
}
}
/*
* cplx.c
*/
func Complexop(n *Node, res *Node) int {
if n != nil && n.Type != nil {
if Iscomplex[n.Type.Etype] != 0 {
goto maybe
}
}
if res != nil && res.Type != nil {
if Iscomplex[res.Type.Etype] != 0 {
goto maybe
}
}
if n.Op == OREAL || n.Op == OIMAG {
goto yes
}
goto no
maybe:
switch n.Op {
case OCONV, // implemented ops
OADD,
OSUB,
OMUL,
OMINUS,
OCOMPLEX,
OREAL,
OIMAG:
goto yes
case ODOT,
ODOTPTR,
OINDEX,
OIND,
ONAME:
goto yes
}
//dump("\ncomplex-no", n);
no:
return 0
//dump("\ncomplex-yes", n);
yes:
return 1
}
func Complexmove(f *Node, t *Node) {
var ft int
var tt int
var n1 Node
var n2 Node
var n3 Node
var n4 Node
var tmp Node
if Debug['g'] != 0 {
Dump("\ncomplexmove-f", f)
Dump("complexmove-t", t)
}
if !(t.Addable != 0) {
Fatal("complexmove: to not addable")
}
ft = Simsimtype(f.Type)
tt = Simsimtype(t.Type)
switch uint32(ft)<<16 | uint32(tt) {
default:
Fatal("complexmove: unknown conversion: %v -> %v\n", Tconv(f.Type, 0), Tconv(t.Type, 0))
fallthrough
// complex to complex move/convert.
// make f addable.
// also use temporary if possible stack overlap.
case TCOMPLEX64<<16 | TCOMPLEX64,
TCOMPLEX64<<16 | TCOMPLEX128,
TCOMPLEX128<<16 | TCOMPLEX64,
TCOMPLEX128<<16 | TCOMPLEX128:
if !(f.Addable != 0) || overlap_cplx(f, t) != 0 {
Tempname(&tmp, f.Type)
Complexmove(f, &tmp)
f = &tmp
}
subnode(&n1, &n2, f)
subnode(&n3, &n4, t)
Thearch.Cgen(&n1, &n3)
Thearch.Cgen(&n2, &n4)
}
}
func Complexgen(n *Node, res *Node) {
var nl *Node
var nr *Node
var tnl Node
var tnr Node
var n1 Node
var n2 Node
var tmp Node
var tl int
var tr int
if Debug['g'] != 0 {
Dump("\ncomplexgen-n", n)
Dump("complexgen-res", res)
}
for n.Op == OCONVNOP {
n = n.Left
}
// pick off float/complex opcodes
switch n.Op {
case OCOMPLEX:
if res.Addable != 0 {
subnode(&n1, &n2, res)
Tempname(&tmp, n1.Type)
Thearch.Cgen(n.Left, &tmp)
Thearch.Cgen(n.Right, &n2)
Thearch.Cgen(&tmp, &n1)
return
}
case OREAL,
OIMAG:
nl = n.Left
if !(nl.Addable != 0) {
Tempname(&tmp, nl.Type)
Complexgen(nl, &tmp)
nl = &tmp
}
subnode(&n1, &n2, nl)
if n.Op == OREAL {
Thearch.Cgen(&n1, res)
return
}
Thearch.Cgen(&n2, res)
return
}
// perform conversion from n to res
tl = Simsimtype(res.Type)
tl = cplxsubtype(tl)
tr = Simsimtype(n.Type)
tr = cplxsubtype(tr)
if tl != tr {
if !(n.Addable != 0) {
Tempname(&n1, n.Type)
Complexmove(n, &n1)
n = &n1
}
Complexmove(n, res)
return
}
if !(res.Addable != 0) {
Thearch.Igen(res, &n1, nil)
Thearch.Cgen(n, &n1)
Thearch.Regfree(&n1)
return
}
if n.Addable != 0 {
Complexmove(n, res)
return
}
switch n.Op {
default:
Dump("complexgen: unknown op", n)
Fatal("complexgen: unknown op %v", Oconv(int(n.Op), 0))
fallthrough
case ODOT,
ODOTPTR,
OINDEX,
OIND,
ONAME, // PHEAP or PPARAMREF var
OCALLFUNC,
OCALLMETH,
OCALLINTER:
Thearch.Igen(n, &n1, res)
Complexmove(&n1, res)
Thearch.Regfree(&n1)
return
case OCONV,
OADD,
OSUB,
OMUL,
OMINUS,
OCOMPLEX,
OREAL,
OIMAG:
break
}
nl = n.Left
if nl == nil {
return
}
nr = n.Right
// make both sides addable in ullman order
if nr != nil {
if nl.Ullman > nr.Ullman && !(nl.Addable != 0) {
Tempname(&tnl, nl.Type)
Thearch.Cgen(nl, &tnl)
nl = &tnl
}
if !(nr.Addable != 0) {
Tempname(&tnr, nr.Type)
Thearch.Cgen(nr, &tnr)
nr = &tnr
}
}
if !(nl.Addable != 0) {
Tempname(&tnl, nl.Type)
Thearch.Cgen(nl, &tnl)
nl = &tnl
}
switch n.Op {
default:
Fatal("complexgen: unknown op %v", Oconv(int(n.Op), 0))
case OCONV:
Complexmove(nl, res)
case OMINUS:
complexminus(nl, res)
case OADD,
OSUB:
complexadd(int(n.Op), nl, nr, res)
case OMUL:
complexmul(nl, nr, res)
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gc
import "fmt"
// case OADD:
// if(n->right->op == OLITERAL) {
// v = n->right->vconst;
// naddr(n->left, a, canemitcode);
// } else
// if(n->left->op == OLITERAL) {
// v = n->left->vconst;
// naddr(n->right, a, canemitcode);
// } else
// goto bad;
// a->offset += v;
// break;
/*
* a function named init is a special case.
* it is called by the initialization before
* main is run. to make it unique within a
* package and also uncallable, the name,
* normally "pkg.init", is altered to "pkg.init·1".
*/
var renameinit_initgen int
func renameinit() *Sym {
renameinit_initgen++
namebuf = fmt.Sprintf("init·%d", renameinit_initgen)
return Lookup(namebuf)
}
/*
* hand-craft the following initialization code
* var initdone· uint8 (1)
* func init() (2)
* if initdone· != 0 { (3)
* if initdone· == 2 (4)
* return
* throw(); (5)
* }
* initdone· = 1; (6)
* // over all matching imported symbols
* <pkg>.init() (7)
* { <init stmts> } (8)
* init·<n>() // if any (9)
* initdone· = 2; (10)
* return (11)
* }
*/
func anyinit(n *NodeList) int {
var h uint32
var s *Sym
var l *NodeList
// are there any interesting init statements
for l = n; l != nil; l = l.Next {
switch l.N.Op {
case ODCLFUNC,
ODCLCONST,
ODCLTYPE,
OEMPTY:
break
case OAS:
if isblank(l.N.Left) && candiscard(l.N.Right) != 0 {
break
}
fallthrough
// fall through
default:
return 1
}
}
// is this main
if localpkg.Name == "main" {
return 1
}
// is there an explicit init function
namebuf = fmt.Sprintf("init·1")
s = Lookup(namebuf)
if s.Def != nil {
return 1
}
// are there any imported init functions
for h = 0; h < NHASH; h++ {
for s = hash[h]; s != nil; s = s.Link {
if s.Name[0] != 'i' || s.Name != "init" {
continue
}
if s.Def == nil {
continue
}
return 1
}
}
// then none
return 0
}
func fninit(n *NodeList) {
var i int
var gatevar *Node
var a *Node
var b *Node
var fn *Node
var r *NodeList
var h uint32
var s *Sym
var initsym *Sym
if Debug['A'] != 0 {
// sys.go or unsafe.go during compiler build
return
}
n = initfix(n)
if !(anyinit(n) != 0) {
return
}
r = nil
// (1)
namebuf = fmt.Sprintf("initdone·")
gatevar = newname(Lookup(namebuf))
addvar(gatevar, Types[TUINT8], PEXTERN)
// (2)
Maxarg = 0
namebuf = fmt.Sprintf("init")
fn = Nod(ODCLFUNC, nil, nil)
initsym = Lookup(namebuf)
fn.Nname = newname(initsym)
fn.Nname.Defn = fn
fn.Nname.Ntype = Nod(OTFUNC, nil, nil)
declare(fn.Nname, PFUNC)
funchdr(fn)
// (3)
a = Nod(OIF, nil, nil)
a.Ntest = Nod(ONE, gatevar, Nodintconst(0))
r = list(r, a)
// (4)
b = Nod(OIF, nil, nil)
b.Ntest = Nod(OEQ, gatevar, Nodintconst(2))
b.Nbody = list1(Nod(ORETURN, nil, nil))
a.Nbody = list1(b)
// (5)
b = syslook("throwinit", 0)
b = Nod(OCALL, b, nil)
a.Nbody = list(a.Nbody, b)
// (6)
a = Nod(OAS, gatevar, Nodintconst(1))
r = list(r, a)
// (7)
for h = 0; h < NHASH; h++ {
for s = hash[h]; s != nil; s = s.Link {
if s.Name[0] != 'i' || s.Name != "init" {
continue
}
if s.Def == nil {
continue
}
if s == initsym {
continue
}
// could check that it is fn of no args/returns
a = Nod(OCALL, s.Def, nil)
r = list(r, a)
}
}
// (8)
r = concat(r, n)
// (9)
// could check that it is fn of no args/returns
for i = 1; ; i++ {
namebuf = fmt.Sprintf("init·%d", i)
s = Lookup(namebuf)
if s.Def == nil {
break
}
a = Nod(OCALL, s.Def, nil)
r = list(r, a)
}
// (10)
a = Nod(OAS, gatevar, Nodintconst(2))
r = list(r, a)
// (11)
a = Nod(ORETURN, nil, nil)
r = list(r, a)
exportsym(fn.Nname)
fn.Nbody = r
funcbody(fn)
Curfn = fn
typecheck(&fn, Etop)
typechecklist(r, Etop)
Curfn = nil
funccompile(fn)
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
package gc
import (
"cmd/internal/obj"
"strconv"
"strings"
)
func bool2int(b bool) int {
if b {
return 1
}
return 0
}
func (n *Node) Line() string {
return obj.Linklinefmt(Ctxt, int(n.Lineno), false, false)
}
func atoi(s string) int {
// NOTE: Not strconv.Atoi, accepts hex and octal prefixes.
n, _ := strconv.ParseInt(s, 0, 0)
return int(n)
}
func isalnum(c int) bool {
return isalpha(c) || isdigit(c)
}
func isalpha(c int) bool {
return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'
}
func isdigit(c int) bool {
return '0' <= c && c <= '9'
}
func plan9quote(s string) string {
if s == "" {
goto needquote
}
for i := 0; i < len(s); i++ {
if s[i] <= ' ' || s[i] == '\'' {
goto needquote
}
}
return s
needquote:
return "'" + strings.Replace(s, "'", "''", -1) + "'"
}
// simulation of int(*s++) in C
func intstarstringplusplus(s string) (int, string) {
if s == "" {
return 0, ""
}
return int(s[0]), s[1:]
}
// strings.Compare, introduced in Go 1.5.
func stringsCompare(a, b string) int {
if a == b {
return 0
}
if a < b {
return -1
}
return +1
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -87,6 +87,7 @@ const (
REGEXT = REG_R10
REGG = REGEXT - 0
REGM = REGEXT - 1
REGCTXT = REG_R7
REGTMP = REG_R11
REGSP = REG_R13
REGLINK = REG_R14
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -590,4 +590,5 @@ const (
FREGRET = REG_F0
REGSP = REG_SP
REGTMP = REG_DI
REGCTXT = REG_DX
)
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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