mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
cmd/internal/obj: fix tail call in non-zero frame leaf function on MIPS and S390X
A "RET f(SB)" wasn't assembled correctly in a leaf function with non-zero frame size. Follows CL 371034, for MIPS(32/64)(be/le) and S390X. Other architectures seem to do it right. Add a test. Change-Id: I41349a7ae9862b924f3a3de2bcb55b782061ce21 Reviewed-on: https://go-review.googlesource.com/c/go/+/371214 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
9e85dc5f18
commit
67917c3d78
@ -466,9 +466,15 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q = c.newprog()
|
q = c.newprog()
|
||||||
q.As = AJMP
|
q.As = AJMP
|
||||||
q.Pos = p.Pos
|
q.Pos = p.Pos
|
||||||
q.To.Type = obj.TYPE_MEM
|
if retSym != nil { // retjmp
|
||||||
q.To.Offset = 0
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
q.To.Reg = REGLINK
|
q.To.Name = obj.NAME_EXTERN
|
||||||
|
q.To.Sym = retSym
|
||||||
|
} else {
|
||||||
|
q.To.Type = obj.TYPE_MEM
|
||||||
|
q.To.Reg = REGLINK
|
||||||
|
q.To.Offset = 0
|
||||||
|
}
|
||||||
q.Mark |= BRANCH
|
q.Mark |= BRANCH
|
||||||
q.Spadj = +autosize
|
q.Spadj = +autosize
|
||||||
|
|
||||||
|
@ -488,8 +488,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q = obj.Appendp(p, c.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
|
if retTarget == nil {
|
||||||
q.To.Reg = REG_LR
|
q.To.Type = obj.TYPE_REG
|
||||||
|
q.To.Reg = REG_LR
|
||||||
|
} else {
|
||||||
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
|
q.To.Sym = retTarget
|
||||||
|
}
|
||||||
q.Mark |= BRANCH
|
q.Mark |= BRANCH
|
||||||
q.Spadj = autosize
|
q.Spadj = autosize
|
||||||
break
|
break
|
||||||
|
@ -10,3 +10,7 @@ TEXT ·f(SB), 4, $8-0
|
|||||||
TEXT ·leaf(SB), 4, $0-0
|
TEXT ·leaf(SB), 4, $0-0
|
||||||
RET ·f3(SB)
|
RET ·f3(SB)
|
||||||
JMP ·unreachable(SB)
|
JMP ·unreachable(SB)
|
||||||
|
|
||||||
|
TEXT ·leaf2(SB), 4, $32-0 // nonzero frame size
|
||||||
|
RET ·f4(SB)
|
||||||
|
JMP ·unreachable(SB)
|
||||||
|
@ -6,8 +6,9 @@ package main
|
|||||||
|
|
||||||
func f()
|
func f()
|
||||||
func leaf()
|
func leaf()
|
||||||
|
func leaf2()
|
||||||
|
|
||||||
var f1called, f2called, f3called bool
|
var f1called, f2called, f3called, f4called bool
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
f()
|
f()
|
||||||
@ -21,11 +22,16 @@ func main() {
|
|||||||
if !f3called {
|
if !f3called {
|
||||||
panic("f3 not called")
|
panic("f3 not called")
|
||||||
}
|
}
|
||||||
|
leaf2()
|
||||||
|
if !f4called {
|
||||||
|
panic("f4 not called")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func f1() { f1called = true }
|
func f1() { f1called = true }
|
||||||
func f2() { f2called = true }
|
func f2() { f2called = true }
|
||||||
func f3() { f3called = true }
|
func f3() { f3called = true }
|
||||||
|
func f4() { f4called = true }
|
||||||
|
|
||||||
func unreachable() {
|
func unreachable() {
|
||||||
panic("unreachable function called")
|
panic("unreachable function called")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user