mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/internal/obj: rip out argp adjustment for wrapper frames
The previous CL made this adjustment unnecessary. The argp field is no longer used by the runtime. Change-Id: I3491eeef4103c6653ec345d604c0acd290af9e8f Reviewed-on: https://go-review.googlesource.com/c/go/+/685356 Reviewed-by: Michael Knyszek <mknyszek@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
parent
7b50024330
commit
6f6c6c5782
11 changed files with 8 additions and 842 deletions
|
|
@ -350,117 +350,6 @@ 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
|
||||||
|
|
||||||
if cursym.Func().Text.From.Sym.Wrapper() {
|
|
||||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
|
||||||
//
|
|
||||||
// MOVW g_panic(g), R1
|
|
||||||
// CMP $0, R1
|
|
||||||
// B.NE checkargp
|
|
||||||
// end:
|
|
||||||
// NOP
|
|
||||||
// ... function ...
|
|
||||||
// checkargp:
|
|
||||||
// MOVW panic_argp(R1), R2
|
|
||||||
// ADD $(autosize+4), R13, R3
|
|
||||||
// CMP R2, R3
|
|
||||||
// B.NE end
|
|
||||||
// ADD $4, R13, R4
|
|
||||||
// MOVW R4, panic_argp(R1)
|
|
||||||
// B end
|
|
||||||
//
|
|
||||||
// The NOP is needed to give the jumps somewhere to land.
|
|
||||||
// It is a liblink NOP, not an ARM NOP: it encodes to 0 instruction bytes.
|
|
||||||
|
|
||||||
p = obj.Appendp(p, newprog)
|
|
||||||
p.As = AMOVW
|
|
||||||
p.From.Type = obj.TYPE_MEM
|
|
||||||
p.From.Reg = REGG
|
|
||||||
p.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // G.panic
|
|
||||||
p.To.Type = obj.TYPE_REG
|
|
||||||
p.To.Reg = REG_R1
|
|
||||||
|
|
||||||
p = obj.Appendp(p, newprog)
|
|
||||||
p.As = ACMP
|
|
||||||
p.From.Type = obj.TYPE_CONST
|
|
||||||
p.From.Offset = 0
|
|
||||||
p.Reg = REG_R1
|
|
||||||
|
|
||||||
// B.NE checkargp
|
|
||||||
bne := obj.Appendp(p, newprog)
|
|
||||||
bne.As = ABNE
|
|
||||||
bne.To.Type = obj.TYPE_BRANCH
|
|
||||||
|
|
||||||
// end: NOP
|
|
||||||
end := obj.Appendp(bne, newprog)
|
|
||||||
end.As = obj.ANOP
|
|
||||||
|
|
||||||
// find end of function
|
|
||||||
var last *obj.Prog
|
|
||||||
for last = end; last.Link != nil; last = last.Link {
|
|
||||||
}
|
|
||||||
|
|
||||||
// MOVW panic_argp(R1), R2
|
|
||||||
mov := obj.Appendp(last, newprog)
|
|
||||||
mov.As = AMOVW
|
|
||||||
mov.From.Type = obj.TYPE_MEM
|
|
||||||
mov.From.Reg = REG_R1
|
|
||||||
mov.From.Offset = 0 // Panic.argp
|
|
||||||
mov.To.Type = obj.TYPE_REG
|
|
||||||
mov.To.Reg = REG_R2
|
|
||||||
|
|
||||||
// B.NE branch target is MOVW above
|
|
||||||
bne.To.SetTarget(mov)
|
|
||||||
|
|
||||||
// ADD $(autosize+4), R13, R3
|
|
||||||
p = obj.Appendp(mov, newprog)
|
|
||||||
p.As = AADD
|
|
||||||
p.From.Type = obj.TYPE_CONST
|
|
||||||
p.From.Offset = int64(autosize) + 4
|
|
||||||
p.Reg = REG_R13
|
|
||||||
p.To.Type = obj.TYPE_REG
|
|
||||||
p.To.Reg = REG_R3
|
|
||||||
|
|
||||||
// CMP R2, R3
|
|
||||||
p = obj.Appendp(p, newprog)
|
|
||||||
p.As = ACMP
|
|
||||||
p.From.Type = obj.TYPE_REG
|
|
||||||
p.From.Reg = REG_R2
|
|
||||||
p.Reg = REG_R3
|
|
||||||
|
|
||||||
// B.NE end
|
|
||||||
p = obj.Appendp(p, newprog)
|
|
||||||
p.As = ABNE
|
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
|
||||||
p.To.SetTarget(end)
|
|
||||||
|
|
||||||
// ADD $4, R13, R4
|
|
||||||
p = obj.Appendp(p, newprog)
|
|
||||||
p.As = AADD
|
|
||||||
p.From.Type = obj.TYPE_CONST
|
|
||||||
p.From.Offset = 4
|
|
||||||
p.Reg = REG_R13
|
|
||||||
p.To.Type = obj.TYPE_REG
|
|
||||||
p.To.Reg = REG_R4
|
|
||||||
|
|
||||||
// MOVW R4, panic_argp(R1)
|
|
||||||
p = obj.Appendp(p, newprog)
|
|
||||||
p.As = AMOVW
|
|
||||||
p.From.Type = obj.TYPE_REG
|
|
||||||
p.From.Reg = REG_R4
|
|
||||||
p.To.Type = obj.TYPE_MEM
|
|
||||||
p.To.Reg = REG_R1
|
|
||||||
p.To.Offset = 0 // Panic.argp
|
|
||||||
|
|
||||||
// B end
|
|
||||||
p = obj.Appendp(p, newprog)
|
|
||||||
p.As = AB
|
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
|
||||||
p.To.SetTarget(end)
|
|
||||||
|
|
||||||
// reset for subsequent passes
|
|
||||||
p = end
|
|
||||||
}
|
|
||||||
|
|
||||||
case obj.ARET:
|
case obj.ARET:
|
||||||
nocache(p)
|
nocache(p)
|
||||||
if cursym.Func().Text.Mark&LEAF != 0 {
|
if cursym.Func().Text.Mark&LEAF != 0 {
|
||||||
|
|
|
||||||
|
|
@ -733,111 +733,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
q1.To.Type = obj.TYPE_REG
|
q1.To.Type = obj.TYPE_REG
|
||||||
q1.To.Reg = REGFP
|
q1.To.Reg = REGFP
|
||||||
|
|
||||||
if c.cursym.Func().Text.From.Sym.Wrapper() {
|
|
||||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
|
||||||
//
|
|
||||||
// MOV g_panic(g), RT1
|
|
||||||
// CBNZ checkargp
|
|
||||||
// end:
|
|
||||||
// NOP
|
|
||||||
// ... function body ...
|
|
||||||
// checkargp:
|
|
||||||
// MOV panic_argp(RT1), RT2
|
|
||||||
// ADD $(autosize+8), RSP, R20
|
|
||||||
// CMP RT2, R20
|
|
||||||
// BNE end
|
|
||||||
// ADD $8, RSP, R20
|
|
||||||
// MOVD R20, panic_argp(RT1)
|
|
||||||
// B end
|
|
||||||
//
|
|
||||||
// The NOP is needed to give the jumps somewhere to land.
|
|
||||||
// It is a liblink NOP, not an ARM64 NOP: it encodes to 0 instruction bytes.
|
|
||||||
q = q1
|
|
||||||
|
|
||||||
// MOV g_panic(g), RT1
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = AMOVD
|
|
||||||
q.From.Type = obj.TYPE_MEM
|
|
||||||
q.From.Reg = REGG
|
|
||||||
q.From.Offset = 4 * int64(c.ctxt.Arch.PtrSize) // G.panic
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REGRT1
|
|
||||||
|
|
||||||
// CBNZ RT1, checkargp
|
|
||||||
cbnz := obj.Appendp(q, c.newprog)
|
|
||||||
cbnz.As = ACBNZ
|
|
||||||
cbnz.From.Type = obj.TYPE_REG
|
|
||||||
cbnz.From.Reg = REGRT1
|
|
||||||
cbnz.To.Type = obj.TYPE_BRANCH
|
|
||||||
|
|
||||||
// Empty branch target at the top of the function body
|
|
||||||
end := obj.Appendp(cbnz, c.newprog)
|
|
||||||
end.As = obj.ANOP
|
|
||||||
|
|
||||||
// find the end of the function
|
|
||||||
var last *obj.Prog
|
|
||||||
for last = end; last.Link != nil; last = last.Link {
|
|
||||||
}
|
|
||||||
|
|
||||||
// MOV panic_argp(RT1), RT2
|
|
||||||
mov := obj.Appendp(last, c.newprog)
|
|
||||||
mov.As = AMOVD
|
|
||||||
mov.From.Type = obj.TYPE_MEM
|
|
||||||
mov.From.Reg = REGRT1
|
|
||||||
mov.From.Offset = 0 // Panic.argp
|
|
||||||
mov.To.Type = obj.TYPE_REG
|
|
||||||
mov.To.Reg = REGRT2
|
|
||||||
|
|
||||||
// CBNZ branches to the MOV above
|
|
||||||
cbnz.To.SetTarget(mov)
|
|
||||||
|
|
||||||
// ADD $(autosize+8), SP, R20
|
|
||||||
q = obj.Appendp(mov, c.newprog)
|
|
||||||
q.As = AADD
|
|
||||||
q.From.Type = obj.TYPE_CONST
|
|
||||||
q.From.Offset = int64(c.autosize) + 8
|
|
||||||
q.Reg = REGSP
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R20
|
|
||||||
|
|
||||||
// CMP RT2, R20
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = ACMP
|
|
||||||
q.From.Type = obj.TYPE_REG
|
|
||||||
q.From.Reg = REGRT2
|
|
||||||
q.Reg = REG_R20
|
|
||||||
|
|
||||||
// BNE end
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = ABNE
|
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
|
||||||
q.To.SetTarget(end)
|
|
||||||
|
|
||||||
// ADD $8, SP, R20
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = AADD
|
|
||||||
q.From.Type = obj.TYPE_CONST
|
|
||||||
q.From.Offset = 8
|
|
||||||
q.Reg = REGSP
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R20
|
|
||||||
|
|
||||||
// MOV R20, panic_argp(RT1)
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = AMOVD
|
|
||||||
q.From.Type = obj.TYPE_REG
|
|
||||||
q.From.Reg = REG_R20
|
|
||||||
q.To.Type = obj.TYPE_MEM
|
|
||||||
q.To.Reg = REGRT1
|
|
||||||
q.To.Offset = 0 // Panic.argp
|
|
||||||
|
|
||||||
// B end
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = AB
|
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
|
||||||
q.To.SetTarget(end)
|
|
||||||
}
|
|
||||||
|
|
||||||
case obj.ARET:
|
case obj.ARET:
|
||||||
nocache(p)
|
nocache(p)
|
||||||
if p.From.Type == obj.TYPE_CONST {
|
if p.From.Type == obj.TYPE_CONST {
|
||||||
|
|
|
||||||
|
|
@ -301,8 +301,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
var q *obj.Prog
|
var q *obj.Prog
|
||||||
var q1 *obj.Prog
|
var q1 *obj.Prog
|
||||||
autosize := int32(0)
|
autosize := int32(0)
|
||||||
var p1 *obj.Prog
|
|
||||||
var p2 *obj.Prog
|
|
||||||
for p := c.cursym.Func().Text; p != nil; p = p.Link {
|
for p := c.cursym.Func().Text; p != nil; p = p.Link {
|
||||||
o := p.As
|
o := p.As
|
||||||
switch o {
|
switch o {
|
||||||
|
|
@ -401,90 +399,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
q.To.Reg = REGSP
|
q.To.Reg = REGSP
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.cursym.Func().Text.From.Sym.Wrapper() && c.cursym.Func().Text.Mark&LEAF == 0 {
|
|
||||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
|
||||||
//
|
|
||||||
// MOV g_panic(g), R20
|
|
||||||
// BEQ R20, end
|
|
||||||
// MOV panic_argp(R20), R24
|
|
||||||
// ADD $(autosize+FIXED_FRAME), R3, R30
|
|
||||||
// BNE R24, R30, end
|
|
||||||
// ADD $FIXED_FRAME, R3, R24
|
|
||||||
// MOV R24, panic_argp(R20)
|
|
||||||
// end:
|
|
||||||
// NOP
|
|
||||||
//
|
|
||||||
// The NOP is needed to give the jumps somewhere to land.
|
|
||||||
// It is a liblink NOP, not a hardware NOP: it encodes to 0 instruction bytes.
|
|
||||||
//
|
|
||||||
// We don't generate this for leaves because that means the wrapped
|
|
||||||
// function was inlined into the wrapper.
|
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
|
||||||
|
|
||||||
q.As = mov
|
|
||||||
q.From.Type = obj.TYPE_MEM
|
|
||||||
q.From.Reg = REGG
|
|
||||||
q.From.Offset = 4 * int64(c.ctxt.Arch.PtrSize) // G.panic
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R20
|
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
|
||||||
q.As = ABEQ
|
|
||||||
q.From.Type = obj.TYPE_REG
|
|
||||||
q.From.Reg = REG_R20
|
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
|
||||||
q.Mark |= BRANCH
|
|
||||||
p1 = q
|
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
|
||||||
q.As = mov
|
|
||||||
q.From.Type = obj.TYPE_MEM
|
|
||||||
q.From.Reg = REG_R20
|
|
||||||
q.From.Offset = 0 // Panic.argp
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R24
|
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
|
||||||
q.As = add
|
|
||||||
q.From.Type = obj.TYPE_CONST
|
|
||||||
q.From.Offset = int64(autosize) + ctxt.Arch.FixedFrameSize
|
|
||||||
q.Reg = REGSP
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R30
|
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
|
||||||
q.As = ABNE
|
|
||||||
q.From.Type = obj.TYPE_REG
|
|
||||||
q.From.Reg = REG_R24
|
|
||||||
q.Reg = REG_R30
|
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
|
||||||
q.Mark |= BRANCH
|
|
||||||
p2 = q
|
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
|
||||||
q.As = add
|
|
||||||
q.From.Type = obj.TYPE_CONST
|
|
||||||
q.From.Offset = ctxt.Arch.FixedFrameSize
|
|
||||||
q.Reg = REGSP
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R24
|
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
|
||||||
q.As = mov
|
|
||||||
q.From.Type = obj.TYPE_REG
|
|
||||||
q.From.Reg = REG_R24
|
|
||||||
q.To.Type = obj.TYPE_MEM
|
|
||||||
q.To.Reg = REG_R20
|
|
||||||
q.To.Offset = 0 // Panic.argp
|
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
|
||||||
|
|
||||||
q.As = obj.ANOP
|
|
||||||
p1.To.SetTarget(q)
|
|
||||||
p2.To.SetTarget(q)
|
|
||||||
}
|
|
||||||
|
|
||||||
case ARET:
|
case ARET:
|
||||||
if p.From.Type == obj.TYPE_CONST {
|
if p.From.Type == obj.TYPE_CONST {
|
||||||
ctxt.Diag("using BECOME (%v) is not supported!", p)
|
ctxt.Diag("using BECOME (%v) is not supported!", p)
|
||||||
|
|
|
||||||
|
|
@ -267,7 +267,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
var q1 *obj.Prog
|
var q1 *obj.Prog
|
||||||
autosize := int32(0)
|
autosize := int32(0)
|
||||||
var p1 *obj.Prog
|
var p1 *obj.Prog
|
||||||
var p2 *obj.Prog
|
|
||||||
for p := c.cursym.Func().Text; p != nil; p = p.Link {
|
for p := c.cursym.Func().Text; p != nil; p = p.Link {
|
||||||
o := p.As
|
o := p.As
|
||||||
switch o {
|
switch o {
|
||||||
|
|
@ -359,90 +358,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
q.To.Reg = REGSP
|
q.To.Reg = REGSP
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.cursym.Func().Text.From.Sym.Wrapper() && c.cursym.Func().Text.Mark&LEAF == 0 {
|
|
||||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
|
||||||
//
|
|
||||||
// MOV g_panic(g), R1
|
|
||||||
// BEQ R1, end
|
|
||||||
// MOV panic_argp(R1), R2
|
|
||||||
// ADD $(autosize+FIXED_FRAME), R29, R3
|
|
||||||
// BNE R2, R3, end
|
|
||||||
// ADD $FIXED_FRAME, R29, R2
|
|
||||||
// MOV R2, panic_argp(R1)
|
|
||||||
// end:
|
|
||||||
// NOP
|
|
||||||
//
|
|
||||||
// The NOP is needed to give the jumps somewhere to land.
|
|
||||||
// It is a liblink NOP, not an mips NOP: it encodes to 0 instruction bytes.
|
|
||||||
//
|
|
||||||
// We don't generate this for leafs because that means the wrapped
|
|
||||||
// function was inlined into the wrapper.
|
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
|
||||||
|
|
||||||
q.As = mov
|
|
||||||
q.From.Type = obj.TYPE_MEM
|
|
||||||
q.From.Reg = REGG
|
|
||||||
q.From.Offset = 4 * int64(c.ctxt.Arch.PtrSize) // G.panic
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R1
|
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
|
||||||
q.As = ABEQ
|
|
||||||
q.From.Type = obj.TYPE_REG
|
|
||||||
q.From.Reg = REG_R1
|
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
|
||||||
q.Mark |= BRANCH
|
|
||||||
p1 = q
|
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
|
||||||
q.As = mov
|
|
||||||
q.From.Type = obj.TYPE_MEM
|
|
||||||
q.From.Reg = REG_R1
|
|
||||||
q.From.Offset = 0 // Panic.argp
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R2
|
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
|
||||||
q.As = add
|
|
||||||
q.From.Type = obj.TYPE_CONST
|
|
||||||
q.From.Offset = int64(autosize) + ctxt.Arch.FixedFrameSize
|
|
||||||
q.Reg = REGSP
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R3
|
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
|
||||||
q.As = ABNE
|
|
||||||
q.From.Type = obj.TYPE_REG
|
|
||||||
q.From.Reg = REG_R2
|
|
||||||
q.Reg = REG_R3
|
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
|
||||||
q.Mark |= BRANCH
|
|
||||||
p2 = q
|
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
|
||||||
q.As = add
|
|
||||||
q.From.Type = obj.TYPE_CONST
|
|
||||||
q.From.Offset = ctxt.Arch.FixedFrameSize
|
|
||||||
q.Reg = REGSP
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R2
|
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
|
||||||
q.As = mov
|
|
||||||
q.From.Type = obj.TYPE_REG
|
|
||||||
q.From.Reg = REG_R2
|
|
||||||
q.To.Type = obj.TYPE_MEM
|
|
||||||
q.To.Reg = REG_R1
|
|
||||||
q.To.Offset = 0 // Panic.argp
|
|
||||||
|
|
||||||
q = obj.Appendp(q, newprog)
|
|
||||||
|
|
||||||
q.As = obj.ANOP
|
|
||||||
p1.To.SetTarget(q)
|
|
||||||
p2.To.SetTarget(q)
|
|
||||||
}
|
|
||||||
|
|
||||||
case ARET:
|
case ARET:
|
||||||
if p.From.Type == obj.TYPE_CONST {
|
if p.From.Type == obj.TYPE_CONST {
|
||||||
ctxt.Diag("using BECOME (%v) is not supported!", p)
|
ctxt.Diag("using BECOME (%v) is not supported!", p)
|
||||||
|
|
|
||||||
|
|
@ -806,8 +806,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
autosize := int32(0)
|
autosize := int32(0)
|
||||||
var p1 *obj.Prog
|
|
||||||
var p2 *obj.Prog
|
|
||||||
for p := c.cursym.Func().Text; p != nil; p = p.Link {
|
for p := c.cursym.Func().Text; p != nil; p = p.Link {
|
||||||
o := p.As
|
o := p.As
|
||||||
switch o {
|
switch o {
|
||||||
|
|
@ -967,96 +965,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
q.To.Offset = 24
|
q.To.Offset = 24
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.cursym.Func().Text.From.Sym.Wrapper() {
|
|
||||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
|
||||||
//
|
|
||||||
// MOVD g_panic(g), R22
|
|
||||||
// CMP R22, $0
|
|
||||||
// BEQ end
|
|
||||||
// MOVD panic_argp(R22), R23
|
|
||||||
// ADD $(autosize+8), R1, R24
|
|
||||||
// CMP R23, R24
|
|
||||||
// BNE end
|
|
||||||
// ADD $8, R1, R25
|
|
||||||
// MOVD R25, panic_argp(R22)
|
|
||||||
// end:
|
|
||||||
// NOP
|
|
||||||
//
|
|
||||||
// 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, c.newprog)
|
|
||||||
|
|
||||||
q.As = AMOVD
|
|
||||||
q.From.Type = obj.TYPE_MEM
|
|
||||||
q.From.Reg = REGG
|
|
||||||
q.From.Offset = 4 * int64(c.ctxt.Arch.PtrSize) // G.panic
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R22
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = ACMP
|
|
||||||
q.From.Type = obj.TYPE_REG
|
|
||||||
q.From.Reg = REG_R22
|
|
||||||
q.To.Type = obj.TYPE_CONST
|
|
||||||
q.To.Offset = 0
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = ABEQ
|
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
|
||||||
p1 = q
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = AMOVD
|
|
||||||
q.From.Type = obj.TYPE_MEM
|
|
||||||
q.From.Reg = REG_R22
|
|
||||||
q.From.Offset = 0 // Panic.argp
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R23
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = AADD
|
|
||||||
q.From.Type = obj.TYPE_CONST
|
|
||||||
q.From.Offset = int64(autosize) + c.ctxt.Arch.FixedFrameSize
|
|
||||||
q.Reg = REGSP
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R24
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = ACMP
|
|
||||||
q.From.Type = obj.TYPE_REG
|
|
||||||
q.From.Reg = REG_R23
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R24
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = ABNE
|
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
|
||||||
p2 = q
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = AADD
|
|
||||||
q.From.Type = obj.TYPE_CONST
|
|
||||||
q.From.Offset = c.ctxt.Arch.FixedFrameSize
|
|
||||||
q.Reg = REGSP
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R25
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = AMOVD
|
|
||||||
q.From.Type = obj.TYPE_REG
|
|
||||||
q.From.Reg = REG_R25
|
|
||||||
q.To.Type = obj.TYPE_MEM
|
|
||||||
q.To.Reg = REG_R22
|
|
||||||
q.To.Offset = 0 // Panic.argp
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
|
|
||||||
q.As = obj.ANOP
|
|
||||||
p1.To.SetTarget(q)
|
|
||||||
p2.To.SetTarget(q)
|
|
||||||
}
|
|
||||||
|
|
||||||
case obj.ARET:
|
case obj.ARET:
|
||||||
if p.From.Type == obj.TYPE_CONST {
|
if p.From.Type == obj.TYPE_CONST {
|
||||||
c.ctxt.Diag("using BECOME (%v) is not supported!", p)
|
c.ctxt.Diag("using BECOME (%v) is not supported!", p)
|
||||||
|
|
|
||||||
|
|
@ -564,85 +564,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
prologue.To = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_SP, Offset: 0}
|
prologue.To = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_SP, Offset: 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cursym.Func().Text.From.Sym.Wrapper() {
|
|
||||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
|
||||||
//
|
|
||||||
// MOV g_panic(g), X5
|
|
||||||
// BNE X5, ZERO, adjust
|
|
||||||
// end:
|
|
||||||
// NOP
|
|
||||||
// ...rest of function..
|
|
||||||
// adjust:
|
|
||||||
// MOV panic_argp(X5), X6
|
|
||||||
// ADD $(autosize+FIXED_FRAME), SP, X7
|
|
||||||
// BNE X6, X7, end
|
|
||||||
// ADD $FIXED_FRAME, SP, X6
|
|
||||||
// MOV X6, panic_argp(X5)
|
|
||||||
// JMP end
|
|
||||||
//
|
|
||||||
// The NOP is needed to give the jumps somewhere to land.
|
|
||||||
|
|
||||||
ldpanic := obj.Appendp(prologue, newprog)
|
|
||||||
|
|
||||||
ldpanic.As = AMOV
|
|
||||||
ldpanic.From = obj.Addr{Type: obj.TYPE_MEM, Reg: REGG, Offset: 4 * int64(ctxt.Arch.PtrSize)} // G.panic
|
|
||||||
ldpanic.Reg = obj.REG_NONE
|
|
||||||
ldpanic.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X5}
|
|
||||||
|
|
||||||
bneadj := obj.Appendp(ldpanic, newprog)
|
|
||||||
bneadj.As = ABNE
|
|
||||||
bneadj.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X5}
|
|
||||||
bneadj.Reg = REG_ZERO
|
|
||||||
bneadj.To.Type = obj.TYPE_BRANCH
|
|
||||||
|
|
||||||
endadj := obj.Appendp(bneadj, newprog)
|
|
||||||
endadj.As = obj.ANOP
|
|
||||||
|
|
||||||
last := endadj
|
|
||||||
for last.Link != nil {
|
|
||||||
last = last.Link
|
|
||||||
}
|
|
||||||
|
|
||||||
getargp := obj.Appendp(last, newprog)
|
|
||||||
getargp.As = AMOV
|
|
||||||
getargp.From = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_X5, Offset: 0} // Panic.argp
|
|
||||||
getargp.Reg = obj.REG_NONE
|
|
||||||
getargp.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X6}
|
|
||||||
|
|
||||||
bneadj.To.SetTarget(getargp)
|
|
||||||
|
|
||||||
calcargp := obj.Appendp(getargp, newprog)
|
|
||||||
calcargp.As = AADDI
|
|
||||||
calcargp.From = obj.Addr{Type: obj.TYPE_CONST, Offset: stacksize + ctxt.Arch.FixedFrameSize}
|
|
||||||
calcargp.Reg = REG_SP
|
|
||||||
calcargp.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X7}
|
|
||||||
|
|
||||||
testargp := obj.Appendp(calcargp, newprog)
|
|
||||||
testargp.As = ABNE
|
|
||||||
testargp.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X6}
|
|
||||||
testargp.Reg = REG_X7
|
|
||||||
testargp.To.Type = obj.TYPE_BRANCH
|
|
||||||
testargp.To.SetTarget(endadj)
|
|
||||||
|
|
||||||
adjargp := obj.Appendp(testargp, newprog)
|
|
||||||
adjargp.As = AADDI
|
|
||||||
adjargp.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(ctxt.Arch.PtrSize)}
|
|
||||||
adjargp.Reg = REG_SP
|
|
||||||
adjargp.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X6}
|
|
||||||
|
|
||||||
setargp := obj.Appendp(adjargp, newprog)
|
|
||||||
setargp.As = AMOV
|
|
||||||
setargp.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X6}
|
|
||||||
setargp.Reg = obj.REG_NONE
|
|
||||||
setargp.To = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_X5, Offset: 0} // Panic.argp
|
|
||||||
|
|
||||||
godone := obj.Appendp(setargp, newprog)
|
|
||||||
godone.As = AJAL
|
|
||||||
godone.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_ZERO}
|
|
||||||
godone.To.Type = obj.TYPE_BRANCH
|
|
||||||
godone.To.SetTarget(endadj)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update stack-based offsets.
|
// Update stack-based offsets.
|
||||||
for p := cursym.Func().Text; p != nil; p = p.Link {
|
for p := cursym.Func().Text; p != nil; p = p.Link {
|
||||||
stackOffset(&p.From, stacksize)
|
stackOffset(&p.From, stacksize)
|
||||||
|
|
|
||||||
|
|
@ -384,96 +384,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.cursym.Func().Text.From.Sym.Wrapper() {
|
|
||||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
|
||||||
//
|
|
||||||
// MOVD g_panic(g), R3
|
|
||||||
// CMP R3, $0
|
|
||||||
// BEQ end
|
|
||||||
// MOVD panic_argp(R3), R4
|
|
||||||
// ADD $(autosize+8), R1, R5
|
|
||||||
// CMP R4, R5
|
|
||||||
// BNE end
|
|
||||||
// ADD $8, R1, R6
|
|
||||||
// MOVD R6, panic_argp(R3)
|
|
||||||
// end:
|
|
||||||
// NOP
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
|
|
||||||
q.As = AMOVD
|
|
||||||
q.From.Type = obj.TYPE_MEM
|
|
||||||
q.From.Reg = REGG
|
|
||||||
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, c.newprog)
|
|
||||||
q.As = ACMP
|
|
||||||
q.From.Type = obj.TYPE_REG
|
|
||||||
q.From.Reg = REG_R3
|
|
||||||
q.To.Type = obj.TYPE_CONST
|
|
||||||
q.To.Offset = 0
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = ABEQ
|
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
|
||||||
p1 := q
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = AMOVD
|
|
||||||
q.From.Type = obj.TYPE_MEM
|
|
||||||
q.From.Reg = REG_R3
|
|
||||||
q.From.Offset = 0 // Panic.argp
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R4
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = AADD
|
|
||||||
q.From.Type = obj.TYPE_CONST
|
|
||||||
q.From.Offset = int64(autosize) + c.ctxt.Arch.FixedFrameSize
|
|
||||||
q.Reg = REGSP
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R5
|
|
||||||
|
|
||||||
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, c.newprog)
|
|
||||||
q.As = ABNE
|
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
|
||||||
p2 := q
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = AADD
|
|
||||||
q.From.Type = obj.TYPE_CONST
|
|
||||||
q.From.Offset = c.ctxt.Arch.FixedFrameSize
|
|
||||||
q.Reg = REGSP
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R6
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
q.As = AMOVD
|
|
||||||
q.From.Type = obj.TYPE_REG
|
|
||||||
q.From.Reg = REG_R6
|
|
||||||
q.To.Type = obj.TYPE_MEM
|
|
||||||
q.To.Reg = REG_R3
|
|
||||||
q.To.Offset = 0 // Panic.argp
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
|
||||||
|
|
||||||
q.As = obj.ANOP
|
|
||||||
p1.To.SetTarget(q)
|
|
||||||
p2.To.SetTarget(q)
|
|
||||||
}
|
|
||||||
|
|
||||||
case obj.ARET:
|
case obj.ARET:
|
||||||
retTarget := p.To.Sym
|
retTarget := p.To.Sym
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -202,59 +202,6 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
framesize = 0
|
framesize = 0
|
||||||
} else if s.Func().WasmExport != nil {
|
} else if s.Func().WasmExport != nil {
|
||||||
genWasmExportWrapper(s, appendp)
|
genWasmExportWrapper(s, appendp)
|
||||||
} else if s.Func().Text.From.Sym.Wrapper() {
|
|
||||||
// if g._panic != nil && g._panic.argp == FP {
|
|
||||||
// g._panic.argp = bottom-of-frame
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// MOVD g_panic(g), R0
|
|
||||||
// Get R0
|
|
||||||
// I64Eqz
|
|
||||||
// Not
|
|
||||||
// If
|
|
||||||
// Get SP
|
|
||||||
// I64ExtendI32U
|
|
||||||
// I64Const $framesize+8
|
|
||||||
// I64Add
|
|
||||||
// I64Load panic_argp(R0)
|
|
||||||
// I64Eq
|
|
||||||
// If
|
|
||||||
// MOVD SP, panic_argp(R0)
|
|
||||||
// End
|
|
||||||
// End
|
|
||||||
|
|
||||||
gpanic := obj.Addr{
|
|
||||||
Type: obj.TYPE_MEM,
|
|
||||||
Reg: REGG,
|
|
||||||
Offset: 4 * 8, // g_panic
|
|
||||||
}
|
|
||||||
|
|
||||||
panicargp := obj.Addr{
|
|
||||||
Type: obj.TYPE_MEM,
|
|
||||||
Reg: REG_R0,
|
|
||||||
Offset: 0, // panic.argp
|
|
||||||
}
|
|
||||||
|
|
||||||
p := s.Func().Text
|
|
||||||
p = appendp(p, AMOVD, gpanic, regAddr(REG_R0))
|
|
||||||
|
|
||||||
p = appendp(p, AGet, regAddr(REG_R0))
|
|
||||||
p = appendp(p, AI64Eqz)
|
|
||||||
p = appendp(p, ANot)
|
|
||||||
p = appendp(p, AIf)
|
|
||||||
|
|
||||||
p = appendp(p, AGet, regAddr(REG_SP))
|
|
||||||
p = appendp(p, AI64ExtendI32U)
|
|
||||||
p = appendp(p, AI64Const, constAddr(framesize+8))
|
|
||||||
p = appendp(p, AI64Add)
|
|
||||||
p = appendp(p, AI64Load, panicargp)
|
|
||||||
|
|
||||||
p = appendp(p, AI64Eq)
|
|
||||||
p = appendp(p, AIf)
|
|
||||||
p = appendp(p, AMOVD, regAddr(REG_SP), panicargp)
|
|
||||||
p = appendp(p, AEnd)
|
|
||||||
|
|
||||||
p = appendp(p, AEnd)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if framesize > 0 && s.Func().WasmExport == nil { // genWasmExportWrapper has its own prologue generation
|
if framesize > 0 && s.Func().WasmExport == nil { // genWasmExportWrapper has its own prologue generation
|
||||||
|
|
|
||||||
|
|
@ -676,20 +676,9 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var regEntryTmp0, regEntryTmp1 int16
|
|
||||||
if ctxt.Arch.Family == sys.AMD64 {
|
|
||||||
regEntryTmp0, regEntryTmp1 = REGENTRYTMP0, REGENTRYTMP1
|
|
||||||
} else {
|
|
||||||
regEntryTmp0, regEntryTmp1 = REG_BX, REG_DI
|
|
||||||
}
|
|
||||||
|
|
||||||
var regg int16
|
|
||||||
if !p.From.Sym.NoSplit() {
|
if !p.From.Sym.NoSplit() {
|
||||||
// Emit split check and load G register
|
// Emit split check.
|
||||||
p, regg = stacksplit(ctxt, cursym, p, newprog, autoffset, int32(textarg))
|
p = stacksplit(ctxt, cursym, p, newprog, autoffset, int32(textarg))
|
||||||
} else if p.From.Sym.Wrapper() {
|
|
||||||
// Load G register for the wrapper code
|
|
||||||
p, regg = loadG(ctxt, cursym, p, newprog)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if bpsize > 0 {
|
if bpsize > 0 {
|
||||||
|
|
@ -731,123 +720,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
p.Pos = p.Pos.WithXlogue(src.PosPrologueEnd)
|
p.Pos = p.Pos.WithXlogue(src.PosPrologueEnd)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cursym.Func().Text.From.Sym.Wrapper() {
|
|
||||||
// if g._panic != nil && g._panic.argp == FP {
|
|
||||||
// g._panic.argp = bottom-of-frame
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// MOVQ g_panic(g), regEntryTmp0
|
|
||||||
// TESTQ regEntryTmp0, regEntryTmp0
|
|
||||||
// JNE checkargp
|
|
||||||
// end:
|
|
||||||
// NOP
|
|
||||||
// ... rest of function ...
|
|
||||||
// checkargp:
|
|
||||||
// LEAQ (autoffset+8)(SP), regEntryTmp1
|
|
||||||
// CMPQ panic_argp(regEntryTmp0), regEntryTmp1
|
|
||||||
// JNE end
|
|
||||||
// MOVQ SP, panic_argp(regEntryTmp0)
|
|
||||||
// JMP end
|
|
||||||
//
|
|
||||||
// The NOP is needed to give the jumps somewhere to land.
|
|
||||||
// It is a liblink NOP, not an x86 NOP: it encodes to 0 instruction bytes.
|
|
||||||
//
|
|
||||||
// The layout is chosen to help static branch prediction:
|
|
||||||
// Both conditional jumps are unlikely, so they are arranged to be forward jumps.
|
|
||||||
|
|
||||||
// MOVQ g_panic(g), regEntryTmp0
|
|
||||||
p = obj.Appendp(p, newprog)
|
|
||||||
p.As = AMOVQ
|
|
||||||
p.From.Type = obj.TYPE_MEM
|
|
||||||
p.From.Reg = regg
|
|
||||||
p.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // g_panic
|
|
||||||
p.To.Type = obj.TYPE_REG
|
|
||||||
p.To.Reg = regEntryTmp0
|
|
||||||
if ctxt.Arch.Family == sys.I386 {
|
|
||||||
p.As = AMOVL
|
|
||||||
}
|
|
||||||
|
|
||||||
// TESTQ regEntryTmp0, regEntryTmp0
|
|
||||||
p = obj.Appendp(p, newprog)
|
|
||||||
p.As = ATESTQ
|
|
||||||
p.From.Type = obj.TYPE_REG
|
|
||||||
p.From.Reg = regEntryTmp0
|
|
||||||
p.To.Type = obj.TYPE_REG
|
|
||||||
p.To.Reg = regEntryTmp0
|
|
||||||
if ctxt.Arch.Family == sys.I386 {
|
|
||||||
p.As = ATESTL
|
|
||||||
}
|
|
||||||
|
|
||||||
// JNE checkargp (checkargp to be resolved later)
|
|
||||||
jne := obj.Appendp(p, newprog)
|
|
||||||
jne.As = AJNE
|
|
||||||
jne.To.Type = obj.TYPE_BRANCH
|
|
||||||
|
|
||||||
// end:
|
|
||||||
// NOP
|
|
||||||
end := obj.Appendp(jne, newprog)
|
|
||||||
end.As = obj.ANOP
|
|
||||||
|
|
||||||
// Fast forward to end of function.
|
|
||||||
var last *obj.Prog
|
|
||||||
for last = end; last.Link != nil; last = last.Link {
|
|
||||||
}
|
|
||||||
|
|
||||||
// LEAQ (autoffset+8)(SP), regEntryTmp1
|
|
||||||
p = obj.Appendp(last, newprog)
|
|
||||||
p.As = ALEAQ
|
|
||||||
p.From.Type = obj.TYPE_MEM
|
|
||||||
p.From.Reg = REG_SP
|
|
||||||
p.From.Offset = int64(autoffset) + int64(ctxt.Arch.RegSize)
|
|
||||||
p.To.Type = obj.TYPE_REG
|
|
||||||
p.To.Reg = regEntryTmp1
|
|
||||||
if ctxt.Arch.Family == sys.I386 {
|
|
||||||
p.As = ALEAL
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set jne branch target.
|
|
||||||
jne.To.SetTarget(p)
|
|
||||||
|
|
||||||
// CMPQ panic_argp(regEntryTmp0), regEntryTmp1
|
|
||||||
p = obj.Appendp(p, newprog)
|
|
||||||
p.As = ACMPQ
|
|
||||||
p.From.Type = obj.TYPE_MEM
|
|
||||||
p.From.Reg = regEntryTmp0
|
|
||||||
p.From.Offset = 0 // Panic.argp
|
|
||||||
p.To.Type = obj.TYPE_REG
|
|
||||||
p.To.Reg = regEntryTmp1
|
|
||||||
if ctxt.Arch.Family == sys.I386 {
|
|
||||||
p.As = ACMPL
|
|
||||||
}
|
|
||||||
|
|
||||||
// JNE end
|
|
||||||
p = obj.Appendp(p, newprog)
|
|
||||||
p.As = AJNE
|
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
|
||||||
p.To.SetTarget(end)
|
|
||||||
|
|
||||||
// MOVQ SP, panic_argp(regEntryTmp0)
|
|
||||||
p = obj.Appendp(p, newprog)
|
|
||||||
p.As = AMOVQ
|
|
||||||
p.From.Type = obj.TYPE_REG
|
|
||||||
p.From.Reg = REG_SP
|
|
||||||
p.To.Type = obj.TYPE_MEM
|
|
||||||
p.To.Reg = regEntryTmp0
|
|
||||||
p.To.Offset = 0 // Panic.argp
|
|
||||||
if ctxt.Arch.Family == sys.I386 {
|
|
||||||
p.As = AMOVL
|
|
||||||
}
|
|
||||||
|
|
||||||
// JMP end
|
|
||||||
p = obj.Appendp(p, newprog)
|
|
||||||
p.As = obj.AJMP
|
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
|
||||||
p.To.SetTarget(end)
|
|
||||||
|
|
||||||
// Reset p for following code.
|
|
||||||
p = end
|
|
||||||
}
|
|
||||||
|
|
||||||
var deltasp int32
|
var deltasp int32
|
||||||
for p = cursym.Func().Text; p != nil; p = p.Link {
|
for p = cursym.Func().Text; p != nil; p = p.Link {
|
||||||
pcsize := ctxt.Arch.RegSize
|
pcsize := ctxt.Arch.RegSize
|
||||||
|
|
@ -1028,8 +900,8 @@ func loadG(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgAlloc)
|
||||||
// Append code to p to check for stack split.
|
// Append code to p to check for stack split.
|
||||||
// Appends to (does not overwrite) p.
|
// Appends to (does not overwrite) p.
|
||||||
// Assumes g is in rg.
|
// Assumes g is in rg.
|
||||||
// Returns last new instruction and G register.
|
// Returns last new instruction.
|
||||||
func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgAlloc, framesize int32, textarg int32) (*obj.Prog, int16) {
|
func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgAlloc, framesize int32, textarg int32) *obj.Prog {
|
||||||
cmp := ACMPQ
|
cmp := ACMPQ
|
||||||
lea := ALEAQ
|
lea := ALEAQ
|
||||||
mov := AMOVQ
|
mov := AMOVQ
|
||||||
|
|
@ -1243,7 +1115,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgA
|
||||||
q1.To.SetTarget(spill)
|
q1.To.SetTarget(spill)
|
||||||
}
|
}
|
||||||
|
|
||||||
return end, rg
|
return end
|
||||||
}
|
}
|
||||||
|
|
||||||
func isR15(r int16) bool {
|
func isR15(r int16) bool {
|
||||||
|
|
|
||||||
|
|
@ -959,10 +959,6 @@ func (p *_panic) nextDefer() (func(), bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The assembler adjusts p.argp in wrapper functions that shouldn't
|
|
||||||
// be visible to recover(), so we need to restore it each iteration.
|
|
||||||
p.argp = add(p.startSP, sys.MinFrameSize)
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
for p.deferBitsPtr != nil {
|
for p.deferBitsPtr != nil {
|
||||||
bits := *p.deferBitsPtr
|
bits := *p.deferBitsPtr
|
||||||
|
|
|
||||||
|
|
@ -1000,12 +1000,11 @@ type _defer struct {
|
||||||
//
|
//
|
||||||
// A _panic value must only ever live on the stack.
|
// A _panic value must only ever live on the stack.
|
||||||
//
|
//
|
||||||
// The argp and link fields are stack pointers, but don't need special
|
// The gopanicFP and link fields are stack pointers, but don't need special
|
||||||
// handling during stack growth: because they are pointer-typed and
|
// handling during stack growth: because they are pointer-typed and
|
||||||
// _panic values only live on the stack, regular stack pointer
|
// _panic values only live on the stack, regular stack pointer
|
||||||
// adjustment takes care of them.
|
// adjustment takes care of them.
|
||||||
type _panic struct {
|
type _panic struct {
|
||||||
argp unsafe.Pointer // pointer to arguments of deferred call run during panic; cannot move - known to liblink
|
|
||||||
arg any // argument to panic
|
arg any // argument to panic
|
||||||
link *_panic // link to earlier panic
|
link *_panic // link to earlier panic
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue