mirror of
https://github.com/golang/go
synced 2024-11-19 10:14:44 -07:00
cmd/internal/obj/s390x: make assembler almost concurrency-safe
CL 39922 made the arm assembler concurrency-safe. This CL does the same, but for s390x. The approach is similar: introduce ctxtz 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: Iabf17aa242b70c0b078c2e85dae3d93a5e512372 Reviewed-on: https://go-review.googlesource.com/40371 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Michael Munday <munday@ca.ibm.com>
This commit is contained in:
parent
f95de5c679
commit
1e69245418
@ -727,7 +727,6 @@ type Link struct {
|
|||||||
InlTree InlTree // global inlining tree used by gc/inl.go
|
InlTree InlTree // global inlining tree used by gc/inl.go
|
||||||
Imports []string
|
Imports []string
|
||||||
Plan9privates *LSym
|
Plan9privates *LSym
|
||||||
Printp *Prog
|
|
||||||
Instoffset int64
|
Instoffset int64
|
||||||
Autosize int32
|
Autosize int32
|
||||||
Pc int64
|
Pc int64
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -39,13 +39,11 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||||||
p.From.Class = 0
|
p.From.Class = 0
|
||||||
p.To.Class = 0
|
p.To.Class = 0
|
||||||
|
|
||||||
|
c := ctxtz{ctxt: ctxt, newprog: newprog}
|
||||||
|
|
||||||
// Rewrite BR/BL to symbol as TYPE_BRANCH.
|
// Rewrite BR/BL to symbol as TYPE_BRANCH.
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case ABR,
|
case ABR, ABL, obj.ARET, obj.ADUFFZERO, obj.ADUFFCOPY:
|
||||||
ABL,
|
|
||||||
obj.ARET,
|
|
||||||
obj.ADUFFZERO,
|
|
||||||
obj.ADUFFCOPY:
|
|
||||||
if p.To.Sym != nil {
|
if p.To.Sym != nil {
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
}
|
}
|
||||||
@ -107,13 +105,13 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctxt.Flag_dynlink {
|
if c.ctxt.Flag_dynlink {
|
||||||
rewriteToUseGot(ctxt, p, newprog)
|
c.rewriteToUseGot(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite p, if necessary, to access global data via the global offset table.
|
// 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 *ctxtz) rewriteToUseGot(p *obj.Prog) {
|
||||||
// At the moment EXRL instructions are not emitted by the compiler and only reference local symbols in
|
// At the moment EXRL instructions are not emitted by the compiler and only reference local symbols in
|
||||||
// assembly code.
|
// assembly code.
|
||||||
if p.As == AEXRL {
|
if p.As == AEXRL {
|
||||||
@ -127,13 +125,13 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||||||
// MOVD $sym, Rx becomes MOVD sym@GOT, Rx
|
// MOVD $sym, Rx becomes MOVD sym@GOT, Rx
|
||||||
// MOVD $sym+<off>, Rx becomes MOVD sym@GOT, Rx; ADD <off>, Rx
|
// MOVD $sym+<off>, Rx becomes MOVD sym@GOT, Rx; ADD <off>, Rx
|
||||||
if p.To.Type != obj.TYPE_REG || p.As != AMOVD {
|
if p.To.Type != obj.TYPE_REG || p.As != AMOVD {
|
||||||
ctxt.Diag("do not know how to handle LEA-type insn to non-register in %v with -dynlink", p)
|
c.ctxt.Diag("do not know how to handle LEA-type insn to non-register in %v with -dynlink", p)
|
||||||
}
|
}
|
||||||
p.From.Type = obj.TYPE_MEM
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Name = obj.NAME_GOTREF
|
p.From.Name = obj.NAME_GOTREF
|
||||||
q := p
|
q := p
|
||||||
if p.From.Offset != 0 {
|
if p.From.Offset != 0 {
|
||||||
q = obj.Appendp(p, newprog)
|
q = obj.Appendp(p, c.newprog)
|
||||||
q.As = AADD
|
q.As = AADD
|
||||||
q.From.Type = obj.TYPE_CONST
|
q.From.Type = obj.TYPE_CONST
|
||||||
q.From.Offset = p.From.Offset
|
q.From.Offset = p.From.Offset
|
||||||
@ -142,7 +140,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN {
|
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
|
var source *obj.Addr
|
||||||
// MOVD sym, Ry becomes MOVD sym@GOT, REGTMP; MOVD (REGTMP), Ry
|
// MOVD sym, Ry becomes MOVD sym@GOT, REGTMP; MOVD (REGTMP), Ry
|
||||||
@ -150,7 +148,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.
|
// 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.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
|
||||||
if p.To.Name == obj.NAME_EXTERN && !p.To.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
|
source = &p.From
|
||||||
} else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
|
} else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
|
||||||
@ -165,10 +163,10 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if source.Type != obj.TYPE_MEM {
|
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)
|
p1 := obj.Appendp(p, c.newprog)
|
||||||
p2 := obj.Appendp(p1, newprog)
|
p2 := obj.Appendp(p1, c.newprog)
|
||||||
|
|
||||||
p1.As = AMOVD
|
p1.As = AMOVD
|
||||||
p1.From.Type = obj.TYPE_MEM
|
p1.From.Type = obj.TYPE_MEM
|
||||||
@ -196,13 +194,13 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||||||
|
|
||||||
func preprocess(ctxt *obj.Link, cursym *obj.LSym, 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.
|
// TODO(minux): add morestack short-cuts with small fixed frame-size.
|
||||||
ctxt.Cursym = cursym
|
|
||||||
|
|
||||||
if cursym.Text == nil || cursym.Text.Link == nil {
|
if cursym.Text == nil || cursym.Text.Link == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
p := cursym.Text
|
c := ctxtz{ctxt: ctxt, cursym: cursym, newprog: newprog}
|
||||||
|
|
||||||
|
p := c.cursym.Text
|
||||||
textstksiz := p.To.Offset
|
textstksiz := p.To.Offset
|
||||||
if textstksiz == -8 {
|
if textstksiz == -8 {
|
||||||
// Compatibility hack.
|
// Compatibility hack.
|
||||||
@ -210,16 +208,16 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
textstksiz = 0
|
textstksiz = 0
|
||||||
}
|
}
|
||||||
if textstksiz%8 != 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 p.From3.Offset&obj.NOFRAME != 0 {
|
||||||
if textstksiz != 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)
|
c.cursym.Args = p.To.Val.(int32)
|
||||||
cursym.Locals = int32(textstksiz)
|
c.cursym.Locals = int32(textstksiz)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* find leaf subroutines
|
* find leaf subroutines
|
||||||
@ -228,7 +226,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
var q *obj.Prog
|
var q *obj.Prog
|
||||||
for p := cursym.Text; p != nil; p = p.Link {
|
for p := c.cursym.Text; p != nil; p = p.Link {
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case obj.ATEXT:
|
case obj.ATEXT:
|
||||||
q = p
|
q = p
|
||||||
@ -236,7 +234,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
|
|
||||||
case ABL, ABCL:
|
case ABL, ABCL:
|
||||||
q = p
|
q = p
|
||||||
cursym.Text.Mark &^= LEAF
|
c.cursym.Text.Mark &^= LEAF
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
||||||
case ABC,
|
case ABC,
|
||||||
@ -287,7 +285,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
var pPre *obj.Prog
|
var pPre *obj.Prog
|
||||||
var pPreempt *obj.Prog
|
var pPreempt *obj.Prog
|
||||||
wasSplit := false
|
wasSplit := false
|
||||||
for p := cursym.Text; p != nil; p = p.Link {
|
for p := c.cursym.Text; p != nil; p = p.Link {
|
||||||
pLast = p
|
pLast = p
|
||||||
switch p.As {
|
switch p.As {
|
||||||
case obj.ATEXT:
|
case obj.ATEXT:
|
||||||
@ -301,7 +299,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
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 += int32(ctxt.FixedFrameSize())
|
autosize += int32(c.ctxt.FixedFrameSize())
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.Mark&LEAF != 0 && autosize < obj.StackSmall {
|
if p.Mark&LEAF != 0 && autosize < obj.StackSmall {
|
||||||
@ -315,7 +313,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q := p
|
q := p
|
||||||
|
|
||||||
if p.From3.Offset&obj.NOSPLIT == 0 {
|
if p.From3.Offset&obj.NOSPLIT == 0 {
|
||||||
p, pPreempt = stacksplitPre(ctxt, p, newprog, autosize) // emit pre part of split check
|
p, pPreempt = c.stacksplitPre(p, autosize) // emit pre part of split check
|
||||||
pPre = p
|
pPre = p
|
||||||
wasSplit = true //need post part of split
|
wasSplit = true //need post part of split
|
||||||
}
|
}
|
||||||
@ -326,7 +324,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
// Store link register before decrementing SP, so if a signal comes
|
// Store link register before decrementing SP, so if a signal comes
|
||||||
// during the execution of the function prologue, the traceback
|
// during the execution of the function prologue, the traceback
|
||||||
// code will not see a half-updated stack frame.
|
// code will not see a half-updated stack frame.
|
||||||
q = obj.Appendp(p, newprog)
|
q = obj.Appendp(p, c.newprog)
|
||||||
q.As = AMOVD
|
q.As = AMOVD
|
||||||
q.From.Type = obj.TYPE_REG
|
q.From.Type = obj.TYPE_REG
|
||||||
q.From.Reg = REG_LR
|
q.From.Reg = REG_LR
|
||||||
@ -334,7 +332,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q.To.Reg = REGSP
|
q.To.Reg = REGSP
|
||||||
q.To.Offset = int64(-autosize)
|
q.To.Offset = int64(-autosize)
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = AMOVD
|
q.As = AMOVD
|
||||||
q.From.Type = obj.TYPE_ADDR
|
q.From.Type = obj.TYPE_ADDR
|
||||||
q.From.Offset = int64(-autosize)
|
q.From.Offset = int64(-autosize)
|
||||||
@ -342,19 +340,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q.To.Type = obj.TYPE_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REGSP
|
q.To.Reg = REGSP
|
||||||
q.Spadj = autosize
|
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
|
// A very few functions that do not return to their caller
|
||||||
// (e.g. gogo) are not identified as leaves but still have
|
// (e.g. gogo) are not identified as leaves but still have
|
||||||
// no frame.
|
// no frame.
|
||||||
cursym.Text.Mark |= LEAF
|
c.cursym.Text.Mark |= LEAF
|
||||||
}
|
}
|
||||||
|
|
||||||
if cursym.Text.Mark&LEAF != 0 {
|
if c.cursym.Text.Mark&LEAF != 0 {
|
||||||
cursym.Set(obj.AttrLeaf, true)
|
c.cursym.Set(obj.AttrLeaf, true)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
||||||
//
|
//
|
||||||
// MOVD g_panic(g), R3
|
// MOVD g_panic(g), R3
|
||||||
@ -372,28 +370,28 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
// The NOP is needed to give the jumps somewhere to land.
|
// The NOP is needed to give the jumps somewhere to land.
|
||||||
// It is a liblink NOP, not a s390x NOP: it encodes to 0 instruction bytes.
|
// It is a liblink NOP, not a s390x NOP: it encodes to 0 instruction bytes.
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
|
|
||||||
q.As = AMOVD
|
q.As = AMOVD
|
||||||
q.From.Type = obj.TYPE_MEM
|
q.From.Type = obj.TYPE_MEM
|
||||||
q.From.Reg = REGG
|
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.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REG_R3
|
q.To.Reg = REG_R3
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = ACMP
|
q.As = ACMP
|
||||||
q.From.Type = obj.TYPE_REG
|
q.From.Type = obj.TYPE_REG
|
||||||
q.From.Reg = REG_R3
|
q.From.Reg = REG_R3
|
||||||
q.To.Type = obj.TYPE_CONST
|
q.To.Type = obj.TYPE_CONST
|
||||||
q.To.Offset = 0
|
q.To.Offset = 0
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = ABEQ
|
q.As = ABEQ
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
p1 := q
|
p1 := q
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = AMOVD
|
q.As = AMOVD
|
||||||
q.From.Type = obj.TYPE_MEM
|
q.From.Type = obj.TYPE_MEM
|
||||||
q.From.Reg = REG_R3
|
q.From.Reg = REG_R3
|
||||||
@ -401,35 +399,35 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q.To.Type = obj.TYPE_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REG_R4
|
q.To.Reg = REG_R4
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = AADD
|
q.As = AADD
|
||||||
q.From.Type = obj.TYPE_CONST
|
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.Reg = REGSP
|
||||||
q.To.Type = obj.TYPE_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REG_R5
|
q.To.Reg = REG_R5
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = ACMP
|
q.As = ACMP
|
||||||
q.From.Type = obj.TYPE_REG
|
q.From.Type = obj.TYPE_REG
|
||||||
q.From.Reg = REG_R4
|
q.From.Reg = REG_R4
|
||||||
q.To.Type = obj.TYPE_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REG_R5
|
q.To.Reg = REG_R5
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = ABNE
|
q.As = ABNE
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
p2 := q
|
p2 := q
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = AADD
|
q.As = AADD
|
||||||
q.From.Type = obj.TYPE_CONST
|
q.From.Type = obj.TYPE_CONST
|
||||||
q.From.Offset = ctxt.FixedFrameSize()
|
q.From.Offset = c.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
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = AMOVD
|
q.As = AMOVD
|
||||||
q.From.Type = obj.TYPE_REG
|
q.From.Type = obj.TYPE_REG
|
||||||
q.From.Reg = REG_R6
|
q.From.Reg = REG_R6
|
||||||
@ -437,7 +435,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q.To.Reg = REG_R3
|
q.To.Reg = REG_R3
|
||||||
q.To.Offset = 0 // Panic.argp
|
q.To.Offset = 0 // Panic.argp
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
|
|
||||||
q.As = obj.ANOP
|
q.As = obj.ANOP
|
||||||
p1.Pcond = q
|
p1.Pcond = q
|
||||||
@ -447,7 +445,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
case obj.ARET:
|
case obj.ARET:
|
||||||
retTarget := p.To.Sym
|
retTarget := p.To.Sym
|
||||||
|
|
||||||
if cursym.Text.Mark&LEAF != 0 {
|
if c.cursym.Text.Mark&LEAF != 0 {
|
||||||
if autosize == 0 {
|
if autosize == 0 {
|
||||||
p.As = ABR
|
p.As = ABR
|
||||||
p.From = obj.Addr{}
|
p.From = obj.Addr{}
|
||||||
@ -469,7 +467,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
p.To.Reg = REGSP
|
p.To.Reg = REGSP
|
||||||
p.Spadj = -autosize
|
p.Spadj = -autosize
|
||||||
|
|
||||||
q = obj.Appendp(p, newprog)
|
q = obj.Appendp(p, c.newprog)
|
||||||
q.As = ABR
|
q.As = ABR
|
||||||
q.From = obj.Addr{}
|
q.From = obj.Addr{}
|
||||||
q.To.Type = obj.TYPE_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
@ -489,7 +487,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q = p
|
q = p
|
||||||
|
|
||||||
if autosize != 0 {
|
if autosize != 0 {
|
||||||
q = obj.Appendp(q, newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = AADD
|
q.As = AADD
|
||||||
q.From.Type = obj.TYPE_CONST
|
q.From.Type = obj.TYPE_CONST
|
||||||
q.From.Offset = int64(autosize)
|
q.From.Offset = int64(autosize)
|
||||||
@ -498,7 +496,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q.Spadj = -autosize
|
q.Spadj = -autosize
|
||||||
}
|
}
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = ABR
|
q.As = ABR
|
||||||
q.From = obj.Addr{}
|
q.From = obj.Addr{}
|
||||||
if retTarget == nil {
|
if retTarget == nil {
|
||||||
@ -518,22 +516,22 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if wasSplit {
|
if wasSplit {
|
||||||
stacksplitPost(ctxt, pLast, pPre, pPreempt, newprog, autosize) // emit post part of split check
|
c.stacksplitPost(pLast, pPre, pPreempt, autosize) // emit post part of split check
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func stacksplitPre(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize int32) (*obj.Prog, *obj.Prog) {
|
func (c *ctxtz) stacksplitPre(p *obj.Prog, framesize int32) (*obj.Prog, *obj.Prog) {
|
||||||
var q *obj.Prog
|
var q *obj.Prog
|
||||||
|
|
||||||
// MOVD g_stackguard(g), R3
|
// MOVD g_stackguard(g), R3
|
||||||
p = obj.Appendp(p, newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
|
|
||||||
p.As = AMOVD
|
p.As = AMOVD
|
||||||
p.From.Type = obj.TYPE_MEM
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Reg = REGG
|
p.From.Reg = REGG
|
||||||
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
|
p.From.Offset = 2 * int64(c.ctxt.Arch.PtrSize) // G.stackguard0
|
||||||
if ctxt.Cursym.CFunc() {
|
if c.cursym.CFunc() {
|
||||||
p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
|
p.From.Offset = 3 * int64(c.ctxt.Arch.PtrSize) // G.stackguard1
|
||||||
}
|
}
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REG_R3
|
p.To.Reg = REG_R3
|
||||||
@ -548,7 +546,7 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize
|
|||||||
|
|
||||||
// q1: BLT done
|
// q1: BLT done
|
||||||
|
|
||||||
p = obj.Appendp(p, newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
//q1 = p
|
//q1 = p
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = REG_R3
|
p.From.Reg = REG_R3
|
||||||
@ -571,7 +569,7 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize
|
|||||||
// large stack: SP-framesize < stackguard-StackSmall
|
// large stack: SP-framesize < stackguard-StackSmall
|
||||||
// ADD $-(framesize-StackSmall), SP, R4
|
// ADD $-(framesize-StackSmall), SP, R4
|
||||||
// CMP stackguard, R4
|
// CMP stackguard, R4
|
||||||
p = obj.Appendp(p, newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
|
|
||||||
p.As = AADD
|
p.As = AADD
|
||||||
p.From.Type = obj.TYPE_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
@ -580,7 +578,7 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize
|
|||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REG_R4
|
p.To.Reg = REG_R4
|
||||||
|
|
||||||
p = obj.Appendp(p, newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = REG_R3
|
p.From.Reg = REG_R3
|
||||||
p.Reg = REG_R4
|
p.Reg = REG_R4
|
||||||
@ -603,7 +601,7 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize
|
|||||||
// SUB R3, R4
|
// SUB R3, R4
|
||||||
// MOVD $(framesize+(StackGuard-StackSmall)), TEMP
|
// MOVD $(framesize+(StackGuard-StackSmall)), TEMP
|
||||||
// CMPUBGE TEMP, R4
|
// CMPUBGE TEMP, R4
|
||||||
p = obj.Appendp(p, newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
|
|
||||||
p.As = ACMP
|
p.As = ACMP
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
@ -611,12 +609,12 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize
|
|||||||
p.To.Type = obj.TYPE_CONST
|
p.To.Type = obj.TYPE_CONST
|
||||||
p.To.Offset = obj.StackPreempt
|
p.To.Offset = obj.StackPreempt
|
||||||
|
|
||||||
p = obj.Appendp(p, newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
q = p
|
q = p
|
||||||
p.As = ABEQ
|
p.As = ABEQ
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
|
|
||||||
p = obj.Appendp(p, newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
p.As = AADD
|
p.As = AADD
|
||||||
p.From.Type = obj.TYPE_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = obj.StackGuard
|
p.From.Offset = obj.StackGuard
|
||||||
@ -624,21 +622,21 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize
|
|||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REG_R4
|
p.To.Reg = REG_R4
|
||||||
|
|
||||||
p = obj.Appendp(p, newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
p.As = ASUB
|
p.As = ASUB
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = REG_R3
|
p.From.Reg = REG_R3
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REG_R4
|
p.To.Reg = REG_R4
|
||||||
|
|
||||||
p = obj.Appendp(p, newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
p.As = AMOVD
|
p.As = AMOVD
|
||||||
p.From.Type = obj.TYPE_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall
|
p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REGTMP
|
p.To.Reg = REGTMP
|
||||||
|
|
||||||
p = obj.Appendp(p, newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = REGTMP
|
p.From.Reg = REGTMP
|
||||||
p.Reg = REG_R4
|
p.Reg = REG_R4
|
||||||
@ -649,16 +647,16 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize
|
|||||||
return p, q
|
return p, q
|
||||||
}
|
}
|
||||||
|
|
||||||
func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.Prog, newprog obj.ProgAlloc, framesize int32) *obj.Prog {
|
func (c *ctxtz) stacksplitPost(p *obj.Prog, pPre *obj.Prog, pPreempt *obj.Prog, framesize int32) *obj.Prog {
|
||||||
// Now we are at the end of the function, but logically
|
// Now we are at the end of the function, but logically
|
||||||
// we are still in function prologue. We need to fix the
|
// we are still in function prologue. We need to fix the
|
||||||
// SP data and PCDATA.
|
// SP data and PCDATA.
|
||||||
spfix := obj.Appendp(p, newprog)
|
spfix := obj.Appendp(p, c.newprog)
|
||||||
spfix.As = obj.ANOP
|
spfix.As = obj.ANOP
|
||||||
spfix.Spadj = -framesize
|
spfix.Spadj = -framesize
|
||||||
|
|
||||||
pcdata := obj.Appendp(spfix, newprog)
|
pcdata := obj.Appendp(spfix, c.newprog)
|
||||||
pcdata.Pos = ctxt.Cursym.Text.Pos
|
pcdata.Pos = c.cursym.Text.Pos
|
||||||
pcdata.As = obj.APCDATA
|
pcdata.As = obj.APCDATA
|
||||||
pcdata.From.Type = obj.TYPE_CONST
|
pcdata.From.Type = obj.TYPE_CONST
|
||||||
pcdata.From.Offset = obj.PCDATA_StackMapIndex
|
pcdata.From.Offset = obj.PCDATA_StackMapIndex
|
||||||
@ -666,7 +664,7 @@ func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.P
|
|||||||
pcdata.To.Offset = -1 // pcdata starts at -1 at function entry
|
pcdata.To.Offset = -1 // pcdata starts at -1 at function entry
|
||||||
|
|
||||||
// MOVD LR, R5
|
// MOVD LR, R5
|
||||||
p = obj.Appendp(pcdata, newprog)
|
p = obj.Appendp(pcdata, c.newprog)
|
||||||
pPre.Pcond = p
|
pPre.Pcond = p
|
||||||
p.As = AMOVD
|
p.As = AMOVD
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
@ -678,24 +676,24 @@ func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.P
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BL runtime.morestack(SB)
|
// BL runtime.morestack(SB)
|
||||||
p = obj.Appendp(p, newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
|
|
||||||
p.As = ABL
|
p.As = ABL
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
if ctxt.Cursym.CFunc() {
|
if c.cursym.CFunc() {
|
||||||
p.To.Sym = ctxt.Lookup("runtime.morestackc", 0)
|
p.To.Sym = c.ctxt.Lookup("runtime.morestackc", 0)
|
||||||
} else if ctxt.Cursym.Text.From3.Offset&obj.NEEDCTXT == 0 {
|
} else if c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0 {
|
||||||
p.To.Sym = ctxt.Lookup("runtime.morestack_noctxt", 0)
|
p.To.Sym = c.ctxt.Lookup("runtime.morestack_noctxt", 0)
|
||||||
} else {
|
} else {
|
||||||
p.To.Sym = ctxt.Lookup("runtime.morestack", 0)
|
p.To.Sym = c.ctxt.Lookup("runtime.morestack", 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BR start
|
// BR start
|
||||||
p = obj.Appendp(p, newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
|
|
||||||
p.As = ABR
|
p.As = ABR
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
p.Pcond = ctxt.Cursym.Text.Link
|
p.Pcond = c.cursym.Text.Link
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user