mirror of
https://github.com/golang/go
synced 2024-11-19 06:54:39 -07:00
cmd/internal/obj/ppc64: make assembler almost concurrency-safe
CL 39922 made the arm assembler concurrency-safe. This CL does the same, but for ppc64. The approach is similar: introduce ctxt9 to hold function-local state and thread it through the assembler as necessary. One race remains after this CL, similar to CL 40252. That race is conceptually unrelated to this refactoring, and will be addressed in a separate CL. Passes toolstash-check -all. Updates #15756 Change-Id: Icc37d9a971bed2184c8e66b1a64f4f2e556dc207 Reviewed-on: https://go-review.googlesource.com/40372 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
b5931020b7
commit
f95de5c679
File diff suppressed because it is too large
Load Diff
@ -38,6 +38,8 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
||||
p.From.Class = 0
|
||||
p.To.Class = 0
|
||||
|
||||
c := ctxt9{ctxt: ctxt, newprog: newprog}
|
||||
|
||||
// Rewrite BR/BL to symbol as TYPE_BRANCH.
|
||||
switch p.As {
|
||||
case ABR,
|
||||
@ -100,13 +102,13 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
||||
p.As = AADD
|
||||
}
|
||||
}
|
||||
if ctxt.Flag_dynlink {
|
||||
rewriteToUseGot(ctxt, p, newprog)
|
||||
if c.ctxt.Flag_dynlink {
|
||||
c.rewriteToUseGot(p)
|
||||
}
|
||||
}
|
||||
|
||||
// Rewrite p, if necessary, to access global data via the global offset table.
|
||||
func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
||||
func (c *ctxt9) rewriteToUseGot(p *obj.Prog) {
|
||||
if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO {
|
||||
// ADUFFxxx $offset
|
||||
// becomes
|
||||
@ -116,9 +118,9 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
||||
// BL (CTR)
|
||||
var sym *obj.LSym
|
||||
if p.As == obj.ADUFFZERO {
|
||||
sym = ctxt.Lookup("runtime.duffzero", 0)
|
||||
sym = c.ctxt.Lookup("runtime.duffzero", 0)
|
||||
} else {
|
||||
sym = ctxt.Lookup("runtime.duffcopy", 0)
|
||||
sym = c.ctxt.Lookup("runtime.duffcopy", 0)
|
||||
}
|
||||
offset := p.To.Offset
|
||||
p.As = AMOVD
|
||||
@ -130,19 +132,19 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
||||
p.To.Name = obj.NAME_NONE
|
||||
p.To.Offset = 0
|
||||
p.To.Sym = nil
|
||||
p1 := obj.Appendp(p, newprog)
|
||||
p1 := obj.Appendp(p, c.newprog)
|
||||
p1.As = AADD
|
||||
p1.From.Type = obj.TYPE_CONST
|
||||
p1.From.Offset = offset
|
||||
p1.To.Type = obj.TYPE_REG
|
||||
p1.To.Reg = REG_R12
|
||||
p2 := obj.Appendp(p1, newprog)
|
||||
p2 := obj.Appendp(p1, c.newprog)
|
||||
p2.As = AMOVD
|
||||
p2.From.Type = obj.TYPE_REG
|
||||
p2.From.Reg = REG_R12
|
||||
p2.To.Type = obj.TYPE_REG
|
||||
p2.To.Reg = REG_CTR
|
||||
p3 := obj.Appendp(p2, newprog)
|
||||
p3 := obj.Appendp(p2, c.newprog)
|
||||
p3.As = obj.ACALL
|
||||
p3.From.Type = obj.TYPE_REG
|
||||
p3.From.Reg = REG_R12
|
||||
@ -157,15 +159,15 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
||||
// MOVD $sym, Rx becomes MOVD sym@GOT, Rx
|
||||
// MOVD $sym+<off>, Rx becomes MOVD sym@GOT, Rx; ADD <off>, Rx
|
||||
if p.As != AMOVD {
|
||||
ctxt.Diag("do not know how to handle TYPE_ADDR in %v with -dynlink", p)
|
||||
c.ctxt.Diag("do not know how to handle TYPE_ADDR in %v with -dynlink", p)
|
||||
}
|
||||
if p.To.Type != obj.TYPE_REG {
|
||||
ctxt.Diag("do not know how to handle LEAQ-type insn to non-register in %v with -dynlink", p)
|
||||
c.ctxt.Diag("do not know how to handle LEAQ-type insn to non-register in %v with -dynlink", p)
|
||||
}
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Name = obj.NAME_GOTREF
|
||||
if p.From.Offset != 0 {
|
||||
q := obj.Appendp(p, newprog)
|
||||
q := obj.Appendp(p, c.newprog)
|
||||
q.As = AADD
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = p.From.Offset
|
||||
@ -174,7 +176,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
||||
}
|
||||
}
|
||||
if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN {
|
||||
ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
||||
c.ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
||||
}
|
||||
var source *obj.Addr
|
||||
// MOVx sym, Ry becomes MOVD sym@GOT, REGTMP; MOVx (REGTMP), Ry
|
||||
@ -182,7 +184,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
||||
// An addition may be inserted between the two MOVs if there is an offset.
|
||||
if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
|
||||
if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
|
||||
ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p)
|
||||
c.ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p)
|
||||
}
|
||||
source = &p.From
|
||||
} else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
|
||||
@ -197,10 +199,10 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
||||
return
|
||||
}
|
||||
if source.Type != obj.TYPE_MEM {
|
||||
ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
||||
c.ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
||||
}
|
||||
p1 := obj.Appendp(p, newprog)
|
||||
p2 := obj.Appendp(p1, newprog)
|
||||
p1 := obj.Appendp(p, c.newprog)
|
||||
p2 := obj.Appendp(p1, c.newprog)
|
||||
|
||||
p1.As = AMOVD
|
||||
p1.From.Type = obj.TYPE_MEM
|
||||
@ -228,13 +230,13 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
||||
|
||||
func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
// TODO(minux): add morestack short-cuts with small fixed frame-size.
|
||||
ctxt.Cursym = cursym
|
||||
|
||||
if cursym.Text == nil || cursym.Text.Link == nil {
|
||||
return
|
||||
}
|
||||
|
||||
p := cursym.Text
|
||||
c := ctxt9{ctxt: ctxt, cursym: cursym, newprog: newprog}
|
||||
|
||||
p := c.cursym.Text
|
||||
textstksiz := p.To.Offset
|
||||
if textstksiz == -8 {
|
||||
// Compatibility hack.
|
||||
@ -242,16 +244,16 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
textstksiz = 0
|
||||
}
|
||||
if textstksiz%8 != 0 {
|
||||
ctxt.Diag("frame size %d not a multiple of 8", textstksiz)
|
||||
c.ctxt.Diag("frame size %d not a multiple of 8", textstksiz)
|
||||
}
|
||||
if p.From3.Offset&obj.NOFRAME != 0 {
|
||||
if textstksiz != 0 {
|
||||
ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", textstksiz)
|
||||
c.ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", textstksiz)
|
||||
}
|
||||
}
|
||||
|
||||
cursym.Args = p.To.Val.(int32)
|
||||
cursym.Locals = int32(textstksiz)
|
||||
c.cursym.Args = p.To.Val.(int32)
|
||||
c.cursym.Locals = int32(textstksiz)
|
||||
|
||||
/*
|
||||
* find leaf subroutines
|
||||
@ -262,7 +264,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
|
||||
var q *obj.Prog
|
||||
var q1 *obj.Prog
|
||||
for p := cursym.Text; p != nil; p = p.Link {
|
||||
for p := c.cursym.Text; p != nil; p = p.Link {
|
||||
switch p.As {
|
||||
/* too hard, just leave alone */
|
||||
case obj.ATEXT:
|
||||
@ -368,7 +370,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
ABCL,
|
||||
obj.ADUFFZERO,
|
||||
obj.ADUFFCOPY:
|
||||
cursym.Text.Mark &^= LEAF
|
||||
c.cursym.Text.Mark &^= LEAF
|
||||
fallthrough
|
||||
|
||||
case ABC,
|
||||
@ -429,7 +431,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
autosize := int32(0)
|
||||
var p1 *obj.Prog
|
||||
var p2 *obj.Prog
|
||||
for p := cursym.Text; p != nil; p = p.Link {
|
||||
for p := c.cursym.Text; p != nil; p = p.Link {
|
||||
o := p.As
|
||||
switch o {
|
||||
case obj.ATEXT:
|
||||
@ -443,7 +445,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
if p.From3.Offset&obj.NOFRAME == 0 {
|
||||
// If there is a stack frame at all, it includes
|
||||
// space to save the LR.
|
||||
autosize += int32(ctxt.FixedFrameSize())
|
||||
autosize += int32(c.ctxt.FixedFrameSize())
|
||||
}
|
||||
|
||||
if p.Mark&LEAF != 0 && autosize < obj.StackSmall {
|
||||
@ -456,7 +458,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
|
||||
q = p
|
||||
|
||||
if ctxt.Flag_shared && cursym.Name != "runtime.duffzero" && cursym.Name != "runtime.duffcopy" {
|
||||
if c.ctxt.Flag_shared && c.cursym.Name != "runtime.duffzero" && c.cursym.Name != "runtime.duffcopy" {
|
||||
// When compiling Go into PIC, all functions must start
|
||||
// with instructions to load the TOC pointer into r2:
|
||||
//
|
||||
@ -473,33 +475,33 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
// generate the addis instruction except as part of the
|
||||
// load of a large constant, and in that case there is no
|
||||
// way to use r12 as the source.
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
q.As = AWORD
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = 0x3c4c0000
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
q.As = AWORD
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = 0x38420000
|
||||
rel := obj.Addrel(ctxt.Cursym)
|
||||
rel := obj.Addrel(c.cursym)
|
||||
rel.Off = 0
|
||||
rel.Siz = 8
|
||||
rel.Sym = ctxt.Lookup(".TOC.", 0)
|
||||
rel.Sym = c.ctxt.Lookup(".TOC.", 0)
|
||||
rel.Type = obj.R_ADDRPOWER_PCREL
|
||||
}
|
||||
|
||||
if cursym.Text.From3.Offset&obj.NOSPLIT == 0 {
|
||||
q = stacksplit(ctxt, q, newprog, autosize) // emit split check
|
||||
if c.cursym.Text.From3.Offset&obj.NOSPLIT == 0 {
|
||||
q = c.stacksplit(q, autosize) // emit split check
|
||||
}
|
||||
|
||||
if autosize != 0 {
|
||||
// Make sure to save link register for non-empty frame, even if
|
||||
// it is a leaf function, so that traceback works.
|
||||
if cursym.Text.Mark&LEAF == 0 && autosize >= -BIG && autosize <= BIG {
|
||||
if c.cursym.Text.Mark&LEAF == 0 && autosize >= -BIG && autosize <= BIG {
|
||||
// Use MOVDU to adjust R1 when saving R31, if autosize is small.
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
q.As = AMOVD
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_REG
|
||||
@ -507,7 +509,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REGTMP
|
||||
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
q.As = AMOVDU
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_REG
|
||||
@ -521,7 +523,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
// Store link register before decrementing SP, so if a signal comes
|
||||
// during the execution of the function prologue, the traceback
|
||||
// code will not see a half-updated stack frame.
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
q.As = AMOVD
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_REG
|
||||
@ -529,7 +531,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R29 // REGTMP may be used to synthesize large offset in the next instruction
|
||||
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
q.As = AMOVD
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_REG
|
||||
@ -538,7 +540,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
q.To.Offset = int64(-autosize)
|
||||
q.To.Reg = REGSP
|
||||
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
q.As = AADD
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
@ -547,20 +549,20 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
q.To.Reg = REGSP
|
||||
q.Spadj = +autosize
|
||||
}
|
||||
} else if cursym.Text.Mark&LEAF == 0 {
|
||||
} else if c.cursym.Text.Mark&LEAF == 0 {
|
||||
// A very few functions that do not return to their caller
|
||||
// (e.g. gogo) are not identified as leaves but still have
|
||||
// no frame.
|
||||
cursym.Text.Mark |= LEAF
|
||||
c.cursym.Text.Mark |= LEAF
|
||||
}
|
||||
|
||||
if cursym.Text.Mark&LEAF != 0 {
|
||||
cursym.Set(obj.AttrLeaf, true)
|
||||
if c.cursym.Text.Mark&LEAF != 0 {
|
||||
c.cursym.Set(obj.AttrLeaf, true)
|
||||
break
|
||||
}
|
||||
|
||||
if ctxt.Flag_shared {
|
||||
q = obj.Appendp(q, newprog)
|
||||
if c.ctxt.Flag_shared {
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
q.As = AMOVD
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_REG
|
||||
@ -570,7 +572,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
q.To.Offset = 24
|
||||
}
|
||||
|
||||
if cursym.Text.From3.Offset&obj.WRAPPER != 0 {
|
||||
if c.cursym.Text.From3.Offset&obj.WRAPPER != 0 {
|
||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
||||
//
|
||||
// MOVD g_panic(g), R3
|
||||
@ -588,28 +590,28 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
// The NOP is needed to give the jumps somewhere to land.
|
||||
// It is a liblink NOP, not a ppc64 NOP: it encodes to 0 instruction bytes.
|
||||
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
|
||||
q.As = AMOVD
|
||||
q.From.Type = obj.TYPE_MEM
|
||||
q.From.Reg = REGG
|
||||
q.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // G.panic
|
||||
q.From.Offset = 4 * int64(c.ctxt.Arch.PtrSize) // G.panic
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R3
|
||||
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
q.As = ACMP
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REG_R0
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R3
|
||||
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
q.As = ABEQ
|
||||
q.To.Type = obj.TYPE_BRANCH
|
||||
p1 = q
|
||||
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
q.As = AMOVD
|
||||
q.From.Type = obj.TYPE_MEM
|
||||
q.From.Reg = REG_R3
|
||||
@ -617,35 +619,35 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R4
|
||||
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
q.As = AADD
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = int64(autosize) + ctxt.FixedFrameSize()
|
||||
q.From.Offset = int64(autosize) + c.ctxt.FixedFrameSize()
|
||||
q.Reg = REGSP
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R5
|
||||
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
q.As = ACMP
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REG_R4
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R5
|
||||
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
q.As = ABNE
|
||||
q.To.Type = obj.TYPE_BRANCH
|
||||
p2 = q
|
||||
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
q.As = AADD
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = ctxt.FixedFrameSize()
|
||||
q.From.Offset = c.ctxt.FixedFrameSize()
|
||||
q.Reg = REGSP
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R6
|
||||
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
q.As = AMOVD
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REG_R6
|
||||
@ -653,7 +655,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
q.To.Reg = REG_R3
|
||||
q.To.Offset = 0 // Panic.argp
|
||||
|
||||
q = obj.Appendp(q, newprog)
|
||||
q = obj.Appendp(q, c.newprog)
|
||||
|
||||
q.As = obj.ANOP
|
||||
p1.Pcond = q
|
||||
@ -662,13 +664,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
|
||||
case obj.ARET:
|
||||
if p.From.Type == obj.TYPE_CONST {
|
||||
ctxt.Diag("using BECOME (%v) is not supported!", p)
|
||||
c.ctxt.Diag("using BECOME (%v) is not supported!", p)
|
||||
break
|
||||
}
|
||||
|
||||
retTarget := p.To.Sym
|
||||
|
||||
if cursym.Text.Mark&LEAF != 0 {
|
||||
if c.cursym.Text.Mark&LEAF != 0 {
|
||||
if autosize == 0 {
|
||||
p.As = ABR
|
||||
p.From = obj.Addr{}
|
||||
@ -690,7 +692,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
p.To.Reg = REGSP
|
||||
p.Spadj = -autosize
|
||||
|
||||
q = newprog()
|
||||
q = c.newprog()
|
||||
q.As = ABR
|
||||
q.Pos = p.Pos
|
||||
q.To.Type = obj.TYPE_REG
|
||||
@ -710,7 +712,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REGTMP
|
||||
|
||||
q = newprog()
|
||||
q = c.newprog()
|
||||
q.As = AMOVD
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_REG
|
||||
@ -724,7 +726,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
|
||||
if false {
|
||||
// Debug bad returns
|
||||
q = newprog()
|
||||
q = c.newprog()
|
||||
|
||||
q.As = AMOVD
|
||||
q.Pos = p.Pos
|
||||
@ -740,7 +742,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
}
|
||||
|
||||
if autosize != 0 {
|
||||
q = newprog()
|
||||
q = c.newprog()
|
||||
q.As = AADD
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
@ -753,7 +755,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
p.Link = q
|
||||
}
|
||||
|
||||
q1 = newprog()
|
||||
q1 = c.newprog()
|
||||
q1.As = ABR
|
||||
q1.Pos = p.Pos
|
||||
if retTarget == nil {
|
||||
@ -821,18 +823,18 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
q = p;
|
||||
}
|
||||
*/
|
||||
func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize int32) *obj.Prog {
|
||||
func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p0 := p // save entry point, but skipping the two instructions setting R2 in shared mode
|
||||
|
||||
// MOVD g_stackguard(g), R3
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Reg = REGG
|
||||
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
|
||||
if ctxt.Cursym.CFunc() {
|
||||
p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
|
||||
p.From.Offset = 2 * int64(c.ctxt.Arch.PtrSize) // G.stackguard0
|
||||
if c.cursym.CFunc() {
|
||||
p.From.Offset = 3 * int64(c.ctxt.Arch.PtrSize) // G.stackguard1
|
||||
}
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R3
|
||||
@ -841,7 +843,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
|
||||
if framesize <= obj.StackSmall {
|
||||
// small stack: SP < stackguard
|
||||
// CMP stackguard, SP
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
|
||||
p.As = ACMPU
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -852,7 +854,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
|
||||
// large stack: SP-framesize < stackguard-StackSmall
|
||||
// ADD $-(framesize-StackSmall), SP, R4
|
||||
// CMP stackguard, R4
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
|
||||
p.As = AADD
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
@ -861,7 +863,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R4
|
||||
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
p.As = ACMPU
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R3
|
||||
@ -883,7 +885,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
|
||||
// SUB R3, R4
|
||||
// MOVD $(framesize+(StackGuard-StackSmall)), R31
|
||||
// CMPU R31, R4
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
|
||||
p.As = ACMP
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -891,12 +893,12 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
|
||||
p.To.Type = obj.TYPE_CONST
|
||||
p.To.Offset = obj.StackPreempt
|
||||
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
q = p
|
||||
p.As = ABEQ
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
p.As = AADD
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = obj.StackGuard
|
||||
@ -904,21 +906,21 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R4
|
||||
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
p.As = ASUB
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R3
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R4
|
||||
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REGTMP
|
||||
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
p.As = ACMPU
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REGTMP
|
||||
@ -927,14 +929,14 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
|
||||
}
|
||||
|
||||
// q1: BLT done
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
q1 := p
|
||||
|
||||
p.As = ABLT
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
|
||||
// MOVD LR, R5
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -946,15 +948,15 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
|
||||
}
|
||||
|
||||
var morestacksym *obj.LSym
|
||||
if ctxt.Cursym.CFunc() {
|
||||
morestacksym = ctxt.Lookup("runtime.morestackc", 0)
|
||||
} else if ctxt.Cursym.Text.From3.Offset&obj.NEEDCTXT == 0 {
|
||||
morestacksym = ctxt.Lookup("runtime.morestack_noctxt", 0)
|
||||
if c.cursym.CFunc() {
|
||||
morestacksym = c.ctxt.Lookup("runtime.morestackc", 0)
|
||||
} else if c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0 {
|
||||
morestacksym = c.ctxt.Lookup("runtime.morestack_noctxt", 0)
|
||||
} else {
|
||||
morestacksym = ctxt.Lookup("runtime.morestack", 0)
|
||||
morestacksym = c.ctxt.Lookup("runtime.morestack", 0)
|
||||
}
|
||||
|
||||
if ctxt.Flag_shared {
|
||||
if c.ctxt.Flag_shared {
|
||||
// In PPC64 PIC code, R2 is used as TOC pointer derived from R12
|
||||
// which is the address of function entry point when entering
|
||||
// the function. We need to preserve R2 across call to morestack.
|
||||
@ -963,7 +965,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
|
||||
// 24(SP) is caller's saved R2). Use 8(SP) to save this function's R2.
|
||||
|
||||
// MOVD R12, 8(SP)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R2
|
||||
@ -972,7 +974,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
|
||||
p.To.Offset = 8
|
||||
}
|
||||
|
||||
if ctxt.Flag_dynlink {
|
||||
if c.ctxt.Flag_dynlink {
|
||||
// Avoid calling morestack via a PLT when dynamically linking. The
|
||||
// PLT stubs generated by the system linker on ppc64le when "std r2,
|
||||
// 24(r1)" to save the TOC pointer in their callers stack
|
||||
@ -988,7 +990,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
|
||||
// seems preferable.
|
||||
|
||||
// MOVD $runtime.morestack(SB), R12
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Sym = morestacksym
|
||||
@ -997,7 +999,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
|
||||
p.To.Reg = REG_R12
|
||||
|
||||
// MOVD R12, CTR
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R12
|
||||
@ -1005,7 +1007,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
|
||||
p.To.Reg = REG_CTR
|
||||
|
||||
// BL CTR
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
p.As = obj.ACALL
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R12
|
||||
@ -1013,16 +1015,16 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
|
||||
p.To.Reg = REG_CTR
|
||||
} else {
|
||||
// BL runtime.morestack(SB)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
|
||||
p.As = ABL
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
p.To.Sym = morestacksym
|
||||
}
|
||||
|
||||
if ctxt.Flag_shared {
|
||||
if c.ctxt.Flag_shared {
|
||||
// MOVD 8(SP), R2
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Reg = REGSP
|
||||
@ -1032,13 +1034,13 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
|
||||
}
|
||||
|
||||
// BR start
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
p.As = ABR
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
p.Pcond = p0.Link
|
||||
|
||||
// placeholder for q1's jump target
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = obj.Appendp(p, c.newprog)
|
||||
|
||||
p.As = obj.ANOP // zero-width place holder
|
||||
q1.Pcond = p
|
||||
|
Loading…
Reference in New Issue
Block a user