for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
p = appendpp(p, ppc64.AMOVD, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGSP, 8+frame+lo+i)
}
- // TODO(dfc): https://golang.org/issue/12108
- // If DUFFZERO is used inside a tail call (see genwrapper) it will
- // overwrite the link register.
- } else if false && cnt <= int64(128*gc.Widthptr) {
+ } else if cnt <= int64(128*gc.Widthptr) {
p = appendpp(p, ppc64.AADD, obj.TYPE_CONST, 0, 8+frame+lo-8, obj.TYPE_REG, ppc64.REGRT1, 0)
p.Reg = ppc64.REGSP
p = appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
// The loop leaves R3 on the last zeroed dword
boff = 8
- // TODO(dfc): https://golang.org/issue/12108
- // If DUFFZERO is used inside a tail call (see genwrapper) it will
- // overwrite the link register.
- } else if false && q >= 4 {
+ } else if q >= 4 {
p := gins(ppc64.ASUB, nil, &dst)
p.From.Type = obj.TYPE_CONST
p.From.Offset = 8
break
}
- if p.To.Sym != nil { // retjmp
- p.As = ABR
- p.To.Type = obj.TYPE_BRANCH
- break
- }
+ retTarget := p.To.Sym
if cursym.Text.Mark&LEAF != 0 {
if autosize == 0 {
p.As = ABR
p.From = obj.Addr{}
- p.To.Type = obj.TYPE_REG
- p.To.Reg = REG_LR
+ if retTarget == nil {
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = REG_LR
+ } else {
+ p.To.Type = obj.TYPE_BRANCH
+ p.To.Sym = retTarget
+ }
p.Mark |= BRANCH
break
}
q1 = ctxt.NewProg()
q1.As = ABR
q1.Lineno = p.Lineno
- q1.To.Type = obj.TYPE_REG
- q1.To.Reg = REG_LR
+ if retTarget == nil {
+ q1.To.Type = obj.TYPE_REG
+ q1.To.Reg = REG_LR
+ } else {
+ q1.To.Type = obj.TYPE_BRANCH
+ q1.To.Sym = retTarget
+ }
q1.Mark |= BRANCH
q1.Spadj = +autosize
q1.Link = q.Link
q.Link = q1
-
case AADD:
if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.From.Type == obj.TYPE_CONST {
p.Spadj = int32(-p.From.Offset)
--- /dev/null
+// run
+
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// A generated method with a return value large enough to be
+// initialized by duffzero is not a leaf method, which violated
+// assumptions made by cmd/internal/obj/ppc64.
+
+package main
+
+const N = 9 // values > 8 cause (Super).Method to use duffzero
+
+type Base struct {
+}
+
+func (b *Base) Method() (x [N]uintptr) {
+ return
+}
+
+type Super struct {
+ Base
+}
+
+type T interface {
+ Method() [N]uintptr
+}
+
+func f(q T) {
+ q.Method()
+}
+
+func main() {
+ var s Super
+ f(&s)
+}