Commit 97055dc1 authored by Michael Hudson-Doyle's avatar Michael Hudson-Doyle

cmd/compile, cmd/internal/obj: centralize knowledge of size of fixed part of stack

Shared libraries on ppc64le will require a larger minimum stack frame (because
the ABI mandates that the TOC pointer is available at 24(R1)). Part 2a of
preparing for that is to have all bits of arch-independent and ppc64-specific
codegen that need to know call a function to find out.

Change-Id: I55899f73037e92227813c491049a3bd6f30bd41f
Reviewed-on: https://go-review.googlesource.com/15524Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent a4855812
...@@ -810,10 +810,7 @@ func cgen_wbptr(n, res *Node) { ...@@ -810,10 +810,7 @@ func cgen_wbptr(n, res *Node) {
a := &p.To a := &p.To
a.Type = obj.TYPE_MEM a.Type = obj.TYPE_MEM
a.Reg = int16(Thearch.REGSP) a.Reg = int16(Thearch.REGSP)
a.Offset = 0 a.Offset = Ctxt.FixedFrameSize()
if HasLinkRegister() {
a.Offset += int64(Widthptr)
}
p2 := Thearch.Gins(Thearch.Optoas(OAS, Types[Tptr]), &src, nil) p2 := Thearch.Gins(Thearch.Optoas(OAS, Types[Tptr]), &src, nil)
p2.To = p.To p2.To = p.To
p2.To.Offset += int64(Widthptr) p2.To.Offset += int64(Widthptr)
...@@ -849,10 +846,7 @@ func cgen_wbfat(n, res *Node) { ...@@ -849,10 +846,7 @@ func cgen_wbfat(n, res *Node) {
a := &p.To a := &p.To
a.Type = obj.TYPE_MEM a.Type = obj.TYPE_MEM
a.Reg = int16(Thearch.REGSP) a.Reg = int16(Thearch.REGSP)
a.Offset = 0 a.Offset = Ctxt.FixedFrameSize()
if HasLinkRegister() {
a.Offset += int64(Widthptr)
}
if needType { if needType {
a.Offset += int64(Widthptr) a.Offset += int64(Widthptr)
} }
...@@ -1686,10 +1680,7 @@ func Igen(n *Node, a *Node, res *Node) { ...@@ -1686,10 +1680,7 @@ func Igen(n *Node, a *Node, res *Node) {
a.Op = OINDREG a.Op = OINDREG
a.Reg = int16(Thearch.REGSP) a.Reg = int16(Thearch.REGSP)
a.Addable = true a.Addable = true
a.Xoffset = fp.Width a.Xoffset = fp.Width + Ctxt.FixedFrameSize()
if HasLinkRegister() {
a.Xoffset += int64(Ctxt.Arch.Ptrsize)
}
a.Type = n.Type a.Type = n.Type
return return
...@@ -2219,11 +2210,7 @@ func stkof(n *Node) int64 { ...@@ -2219,11 +2210,7 @@ func stkof(n *Node) int64 {
var flist Iter var flist Iter
t = Structfirst(&flist, Getoutarg(t)) t = Structfirst(&flist, Getoutarg(t))
if t != nil { if t != nil {
w := t.Width return t.Width + Ctxt.FixedFrameSize()
if HasLinkRegister() {
w += int64(Ctxt.Arch.Ptrsize)
}
return w
} }
} }
...@@ -2379,17 +2366,11 @@ func Ginscall(f *Node, proc int) { ...@@ -2379,17 +2366,11 @@ func Ginscall(f *Node, proc int) {
// size of arguments at 0(SP) // size of arguments at 0(SP)
stk.Op = OINDREG stk.Op = OINDREG
stk.Reg = int16(Thearch.REGSP) stk.Reg = int16(Thearch.REGSP)
stk.Xoffset = 0 stk.Xoffset = Ctxt.FixedFrameSize()
if HasLinkRegister() {
stk.Xoffset += int64(Ctxt.Arch.Ptrsize)
}
Thearch.Ginscon(Thearch.Optoas(OAS, Types[TINT32]), int64(Argsize(f.Type)), &stk) Thearch.Ginscon(Thearch.Optoas(OAS, Types[TINT32]), int64(Argsize(f.Type)), &stk)
// FuncVal* at 8(SP) // FuncVal* at 8(SP)
stk.Xoffset = int64(Widthptr) stk.Xoffset = int64(Widthptr) + Ctxt.FixedFrameSize()
if HasLinkRegister() {
stk.Xoffset += int64(Ctxt.Arch.Ptrsize)
}
var reg Node var reg Node
Nodreg(&reg, Types[Tptr], Thearch.REGCALLX2) Nodreg(&reg, Types[Tptr], Thearch.REGCALLX2)
...@@ -2447,10 +2428,7 @@ func cgen_callinter(n *Node, res *Node, proc int) { ...@@ -2447,10 +2428,7 @@ func cgen_callinter(n *Node, res *Node, proc int) {
var nodsp Node var nodsp Node
Nodindreg(&nodsp, Types[Tptr], Thearch.REGSP) Nodindreg(&nodsp, Types[Tptr], Thearch.REGSP)
nodsp.Xoffset = 0 nodsp.Xoffset = Ctxt.FixedFrameSize()
if HasLinkRegister() {
nodsp.Xoffset += int64(Ctxt.Arch.Ptrsize)
}
if proc != 0 { if proc != 0 {
nodsp.Xoffset += 2 * int64(Widthptr) // leave room for size & fn nodsp.Xoffset += 2 * int64(Widthptr) // leave room for size & fn
} }
...@@ -2541,11 +2519,6 @@ func cgen_call(n *Node, proc int) { ...@@ -2541,11 +2519,6 @@ func cgen_call(n *Node, proc int) {
Ginscall(n.Left, proc) Ginscall(n.Left, proc)
} }
func HasLinkRegister() bool {
c := Ctxt.Arch.Thechar
return c != '6' && c != '8'
}
/* /*
* call to n has already been generated. * call to n has already been generated.
* generate: * generate:
...@@ -2568,10 +2541,7 @@ func cgen_callret(n *Node, res *Node) { ...@@ -2568,10 +2541,7 @@ func cgen_callret(n *Node, res *Node) {
nod.Reg = int16(Thearch.REGSP) nod.Reg = int16(Thearch.REGSP)
nod.Addable = true nod.Addable = true
nod.Xoffset = fp.Width nod.Xoffset = fp.Width + Ctxt.FixedFrameSize()
if HasLinkRegister() {
nod.Xoffset += int64(Ctxt.Arch.Ptrsize)
}
nod.Type = fp.Type nod.Type = fp.Type
Cgen_as(res, &nod) Cgen_as(res, &nod)
} }
...@@ -2597,10 +2567,7 @@ func cgen_aret(n *Node, res *Node) { ...@@ -2597,10 +2567,7 @@ func cgen_aret(n *Node, res *Node) {
nod1.Op = OINDREG nod1.Op = OINDREG
nod1.Reg = int16(Thearch.REGSP) nod1.Reg = int16(Thearch.REGSP)
nod1.Addable = true nod1.Addable = true
nod1.Xoffset = fp.Width nod1.Xoffset = fp.Width + Ctxt.FixedFrameSize()
if HasLinkRegister() {
nod1.Xoffset += int64(Ctxt.Arch.Ptrsize)
}
nod1.Type = fp.Type nod1.Type = fp.Type
if res.Op != OREGISTER { if res.Op != OREGISTER {
...@@ -2858,10 +2825,7 @@ func cgen_append(n, res *Node) { ...@@ -2858,10 +2825,7 @@ func cgen_append(n, res *Node) {
arg.Op = OINDREG arg.Op = OINDREG
arg.Reg = int16(Thearch.REGSP) arg.Reg = int16(Thearch.REGSP)
arg.Addable = true arg.Addable = true
arg.Xoffset = 0 arg.Xoffset = Ctxt.FixedFrameSize()
if HasLinkRegister() {
arg.Xoffset = int64(Ctxt.Arch.Ptrsize)
}
arg.Type = Ptrto(Types[TUINT8]) arg.Type = Ptrto(Types[TUINT8])
Cgen(typename(res.Type), &arg) Cgen(typename(res.Type), &arg)
arg.Xoffset += int64(Widthptr) arg.Xoffset += int64(Widthptr)
......
...@@ -568,9 +568,7 @@ fp: ...@@ -568,9 +568,7 @@ fp:
n.Op = OINDREG n.Op = OINDREG
n.Reg = int16(Thearch.REGSP) n.Reg = int16(Thearch.REGSP)
if HasLinkRegister() { n.Xoffset += Ctxt.FixedFrameSize()
n.Xoffset += int64(Ctxt.Arch.Ptrsize)
}
case 1: // input arg case 1: // input arg
n.Class = PPARAM n.Class = PPARAM
......
...@@ -69,10 +69,10 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { ...@@ -69,10 +69,10 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
} }
if cnt < int64(4*gc.Widthptr) { if cnt < int64(4*gc.Widthptr) {
for i := int64(0); i < cnt; i += int64(gc.Widthptr) { for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
p = appendpp(p, ppc64.AMOVD, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGSP, 8+frame+lo+i) p = appendpp(p, ppc64.AMOVD, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGSP, gc.Ctxt.FixedFrameSize()+frame+lo+i)
} }
} else if cnt <= int64(128*gc.Widthptr) { } else if cnt <= int64(128*gc.Widthptr) {
p = appendpp(p, ppc64.AADD, obj.TYPE_CONST, 0, 8+frame+lo-8, obj.TYPE_REG, ppc64.REGRT1, 0) p = appendpp(p, ppc64.AADD, obj.TYPE_CONST, 0, gc.Ctxt.FixedFrameSize()+frame+lo-8, obj.TYPE_REG, ppc64.REGRT1, 0)
p.Reg = ppc64.REGSP p.Reg = ppc64.REGSP
p = appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0) p = appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
f := gc.Sysfunc("duffzero") f := gc.Sysfunc("duffzero")
...@@ -80,7 +80,7 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { ...@@ -80,7 +80,7 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
gc.Afunclit(&p.To, f) gc.Afunclit(&p.To, f)
p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr)) p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr))
} else { } else {
p = appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, 8+frame+lo-8, obj.TYPE_REG, ppc64.REGTMP, 0) p = appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, gc.Ctxt.FixedFrameSize()+frame+lo-8, obj.TYPE_REG, ppc64.REGTMP, 0)
p = appendpp(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT1, 0) p = appendpp(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT1, 0)
p.Reg = ppc64.REGSP p.Reg = ppc64.REGSP
p = appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, ppc64.REGTMP, 0) p = appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, ppc64.REGTMP, 0)
......
...@@ -523,6 +523,19 @@ type Link struct { ...@@ -523,6 +523,19 @@ type Link struct {
Etextp *LSym Etextp *LSym
} }
// The smallest possible offset from the hardware stack pointer to a local
// variable on the stack. Architectures that use a link register save its value
// on the stack in the function prologue and so always have a pointer between
// the hardware stack pointer and the local variable area.
func (ctxt *Link) FixedFrameSize() int64 {
switch ctxt.Arch.Thechar {
case '6', '8':
return 0
default:
return int64(ctxt.Arch.Ptrsize)
}
}
type SymVer struct { type SymVer struct {
Name string Name string
Version int // TODO: make int16 to match LSym.Version? Version int // TODO: make int16 to match LSym.Version?
......
...@@ -595,7 +595,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { ...@@ -595,7 +595,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
return C_LAUTO return C_LAUTO
case obj.NAME_PARAM: case obj.NAME_PARAM:
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8 ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + ctxt.FixedFrameSize()
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
return C_SAUTO return C_SAUTO
} }
...@@ -658,7 +658,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { ...@@ -658,7 +658,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int {
return C_LACON return C_LACON
case obj.NAME_PARAM: case obj.NAME_PARAM:
ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8 ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + ctxt.FixedFrameSize()
if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
return C_SACON return C_SACON
} }
......
...@@ -337,7 +337,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -337,7 +337,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
if p.From3.Offset&obj.NOFRAME == 0 { if p.From3.Offset&obj.NOFRAME == 0 {
// If there is a stack frame at all, it includes // If there is a stack frame at all, it includes
// space to save the LR. // space to save the LR.
autosize += 8 autosize += int32(ctxt.FixedFrameSize())
} }
p.To.Offset = int64(autosize) p.To.Offset = int64(autosize)
...@@ -445,7 +445,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -445,7 +445,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q = obj.Appendp(ctxt, q) q = obj.Appendp(ctxt, q)
q.As = AADD q.As = AADD
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(autosize) + 8 q.From.Offset = int64(autosize) + ctxt.FixedFrameSize()
q.Reg = REGSP q.Reg = REGSP
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R5 q.To.Reg = REG_R5
...@@ -465,7 +465,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -465,7 +465,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q = obj.Appendp(ctxt, q) q = obj.Appendp(ctxt, q)
q.As = AADD q.As = AADD
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = 8 q.From.Offset = ctxt.FixedFrameSize()
q.Reg = REGSP q.Reg = REGSP
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R6 q.To.Reg = REG_R6
......
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