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.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:
|
||||
nocache(p)
|
||||
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.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:
|
||||
nocache(p)
|
||||
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 q1 *obj.Prog
|
||||
autosize := int32(0)
|
||||
var p1 *obj.Prog
|
||||
var p2 *obj.Prog
|
||||
for p := c.cursym.Func().Text; p != nil; p = p.Link {
|
||||
o := p.As
|
||||
switch o {
|
||||
|
|
@ -401,90 +399,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
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:
|
||||
if p.From.Type == obj.TYPE_CONST {
|
||||
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
|
||||
autosize := int32(0)
|
||||
var p1 *obj.Prog
|
||||
var p2 *obj.Prog
|
||||
for p := c.cursym.Func().Text; p != nil; p = p.Link {
|
||||
o := p.As
|
||||
switch o {
|
||||
|
|
@ -359,90 +358,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
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:
|
||||
if p.From.Type == obj.TYPE_CONST {
|
||||
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)
|
||||
var p1 *obj.Prog
|
||||
var p2 *obj.Prog
|
||||
for p := c.cursym.Func().Text; p != nil; p = p.Link {
|
||||
o := p.As
|
||||
switch o {
|
||||
|
|
@ -967,96 +965,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
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:
|
||||
if p.From.Type == obj.TYPE_CONST {
|
||||
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}
|
||||
}
|
||||
|
||||
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.
|
||||
for p := cursym.Func().Text; p != nil; p = p.Link {
|
||||
stackOffset(&p.From, stacksize)
|
||||
|
|
|
|||
|
|
@ -384,96 +384,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
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:
|
||||
retTarget := p.To.Sym
|
||||
|
||||
|
|
|
|||
|
|
@ -202,59 +202,6 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
|
|||
framesize = 0
|
||||
} else if s.Func().WasmExport != nil {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
// Emit split check and load G register
|
||||
p, regg = 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)
|
||||
// Emit split check.
|
||||
p = stacksplit(ctxt, cursym, p, newprog, autoffset, int32(textarg))
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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
|
||||
for p = cursym.Func().Text; p != nil; p = p.Link {
|
||||
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.
|
||||
// Appends to (does not overwrite) p.
|
||||
// Assumes g is in rg.
|
||||
// Returns last new instruction and G register.
|
||||
func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgAlloc, framesize int32, textarg int32) (*obj.Prog, int16) {
|
||||
// Returns last new instruction.
|
||||
func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgAlloc, framesize int32, textarg int32) *obj.Prog {
|
||||
cmp := ACMPQ
|
||||
lea := ALEAQ
|
||||
mov := AMOVQ
|
||||
|
|
@ -1243,7 +1115,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgA
|
|||
q1.To.SetTarget(spill)
|
||||
}
|
||||
|
||||
return end, rg
|
||||
return end
|
||||
}
|
||||
|
||||
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 p.deferBitsPtr != nil {
|
||||
bits := *p.deferBitsPtr
|
||||
|
|
|
|||
|
|
@ -1000,14 +1000,13 @@ type _defer struct {
|
|||
//
|
||||
// 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
|
||||
// _panic values only live on the stack, regular stack pointer
|
||||
// adjustment takes care of them.
|
||||
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
|
||||
link *_panic // link to earlier panic
|
||||
arg any // argument to panic
|
||||
link *_panic // link to earlier panic
|
||||
|
||||
// startPC and startSP track where _panic.start was called.
|
||||
startPC uintptr
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue