The arch backends no longer depend on gc.Node.
Passes toolstash-check -all.
Change-Id: Ic7e49ae0a3ed155a2761c25e17cc341b46333fb4
Reviewed-on: https://go-review.googlesource.com/41196
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
arch.REGSP = x86.REGSP
arch.MAXWIDTH = 1 << 50
- arch.Defframe = defframe
+ arch.ZeroRange = zerorange
arch.Ginsnop = ginsnop
arch.SSAMarkMoves = ssaMarkMoves
// no floating point in note handlers on Plan 9
var isPlan9 = objabi.GOOS == "plan9"
-func defframe(pp *gc.Progs, fn *gc.Node, sz int64) {
- // fill in argument size, stack size
- pp.Text.To.Type = obj.TYPE_TEXTSIZE
-
- pp.Text.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
- frame := uint32(gc.Rnd(sz, int64(gc.Widthreg)))
- pp.Text.To.Offset = int64(frame)
-
- // insert code to zero ambiguously live variables
- // so that the garbage collector only sees initialized values
- // when it looks for pointers.
- p := pp.Text
-
- hi := int64(0)
- lo := hi
- ax := uint32(0)
- x0 := uint32(0)
-
- // iterate through declarations - they are sorted in decreasing xoffset order.
- for _, n := range fn.Func.Dcl {
- if !n.Name.Needzero() {
- continue
- }
- if n.Class != gc.PAUTO {
- gc.Fatalf("needzero class %d", n.Class)
- }
- if n.Type.Width%int64(gc.Widthptr) != 0 || n.Xoffset%int64(gc.Widthptr) != 0 || n.Type.Width == 0 {
- gc.Fatalf("var %L has size %d offset %d", n, int(n.Type.Width), int(n.Xoffset))
- }
-
- if lo != hi && n.Xoffset+n.Type.Width >= lo-int64(2*gc.Widthreg) {
- // merge with range we already have
- lo = n.Xoffset
-
- continue
- }
-
- // zero old range
- p = zerorange(pp, p, int64(frame), lo, hi, &ax, &x0)
-
- // set new range
- hi = n.Xoffset + n.Type.Width
-
- lo = n.Xoffset
- }
-
- // zero final range
- zerorange(pp, p, int64(frame), lo, hi, &ax, &x0)
-}
-
// DUFFZERO consists of repeated blocks of 4 MOVUPSs + ADD,
// See runtime/mkduff.go.
const (
return -dzClearStep * (dzBlockLen - tailSteps)
}
-func zerorange(pp *gc.Progs, p *obj.Prog, frame int64, lo int64, hi int64, ax *uint32, x0 *uint32) *obj.Prog {
- cnt := hi - lo
+func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, state *uint32) *obj.Prog {
+ const (
+ ax = 1 << iota
+ x0
+ )
+
if cnt == 0 {
return p
}
if cnt%int64(gc.Widthptr) != 0 {
gc.Fatalf("zerorange count not a multiple of widthptr %d", cnt)
}
- if *ax == 0 {
+ if *state&ax == 0 {
p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
- *ax = 1
+ *state |= ax
}
- p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, frame+lo)
- lo += int64(gc.Widthptr)
+ p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, off)
+ off += int64(gc.Widthptr)
cnt -= int64(gc.Widthptr)
}
if cnt == 8 {
- if *ax == 0 {
+ if *state&ax == 0 {
p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
- *ax = 1
+ *state |= ax
}
- p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, frame+lo)
+ p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, off)
} else if !isPlan9 && cnt <= int64(8*gc.Widthreg) {
- if *x0 == 0 {
+ if *state&x0 == 0 {
p = pp.Appendpp(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_REG, x86.REG_X0, 0)
- *x0 = 1
+ *state |= x0
}
for i := int64(0); i < cnt/16; i++ {
- p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_SP, frame+lo+i*16)
+ p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_SP, off+i*16)
}
if cnt%16 != 0 {
- p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_SP, frame+lo+cnt-int64(16))
+ p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_SP, off+cnt-int64(16))
}
} else if !gc.Nacl && !isPlan9 && (cnt <= int64(128*gc.Widthreg)) {
- if *x0 == 0 {
+ if *state&x0 == 0 {
p = pp.Appendpp(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_REG, x86.REG_X0, 0)
- *x0 = 1
+ *state |= x0
}
- p = pp.Appendpp(p, leaptr, obj.TYPE_MEM, x86.REG_SP, frame+lo+dzDI(cnt), obj.TYPE_REG, x86.REG_DI, 0)
+ p = pp.Appendpp(p, leaptr, obj.TYPE_MEM, x86.REG_SP, off+dzDI(cnt), obj.TYPE_REG, x86.REG_DI, 0)
p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_ADDR, 0, dzOff(cnt))
p.To.Sym = gc.Duffzero
p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_DI, -int64(8))
}
} else {
- if *ax == 0 {
+ if *state&ax == 0 {
p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
- *ax = 1
+ *state |= ax
}
p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, cnt/int64(gc.Widthreg), obj.TYPE_REG, x86.REG_CX, 0)
- p = pp.Appendpp(p, leaptr, obj.TYPE_MEM, x86.REG_SP, frame+lo, obj.TYPE_REG, x86.REG_DI, 0)
+ p = pp.Appendpp(p, leaptr, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
p = pp.Appendpp(p, x86.AREP, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
p = pp.Appendpp(p, x86.ASTOSQ, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
}
arch.REGSP = arm.REGSP
arch.MAXWIDTH = (1 << 32) - 1
- arch.Defframe = defframe
+ arch.ZeroRange = zerorange
arch.Ginsnop = ginsnop
arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
"cmd/internal/obj/arm"
)
-func defframe(pp *gc.Progs, fn *gc.Node, sz int64) {
- // fill in argument size, stack size
- pp.Text.To.Type = obj.TYPE_TEXTSIZE
-
- pp.Text.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
- frame := uint32(gc.Rnd(sz, int64(gc.Widthreg)))
- pp.Text.To.Offset = int64(frame)
-
- // insert code to contain ambiguously live variables
- // so that garbage collector only sees initialized values
- // when it looks for pointers.
- p := pp.Text
-
- hi := int64(0)
- lo := hi
- r0 := uint32(0)
- for _, n := range fn.Func.Dcl {
- if !n.Name.Needzero() {
- continue
- }
- if n.Class != gc.PAUTO {
- gc.Fatalf("needzero class %d", n.Class)
- }
- if n.Type.Width%int64(gc.Widthptr) != 0 || n.Xoffset%int64(gc.Widthptr) != 0 || n.Type.Width == 0 {
- gc.Fatalf("var %L has size %d offset %d", n, int(n.Type.Width), int(n.Xoffset))
- }
- if lo != hi && n.Xoffset+n.Type.Width >= lo-int64(2*gc.Widthptr) {
- // merge with range we already have
- lo = gc.Rnd(n.Xoffset, int64(gc.Widthptr))
-
- continue
- }
-
- // zero old range
- p = zerorange(pp, p, int64(frame), lo, hi, &r0)
-
- // set new range
- hi = n.Xoffset + n.Type.Width
-
- lo = n.Xoffset
- }
-
- // zero final range
- zerorange(pp, p, int64(frame), lo, hi, &r0)
-}
-
-func zerorange(pp *gc.Progs, p *obj.Prog, frame int64, lo int64, hi int64, r0 *uint32) *obj.Prog {
- cnt := hi - lo
+func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, r0 *uint32) *obj.Prog {
if cnt == 0 {
return p
}
if cnt < int64(4*gc.Widthptr) {
for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
- p = pp.Appendpp(p, arm.AMOVW, obj.TYPE_REG, arm.REG_R0, 0, obj.TYPE_MEM, arm.REGSP, 4+frame+lo+i)
+ p = pp.Appendpp(p, arm.AMOVW, obj.TYPE_REG, arm.REG_R0, 0, obj.TYPE_MEM, arm.REGSP, 4+off+i)
}
} else if !gc.Nacl && (cnt <= int64(128*gc.Widthptr)) {
- p = pp.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0, 4+frame+lo, obj.TYPE_REG, arm.REG_R1, 0)
+ p = pp.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0, 4+off, obj.TYPE_REG, arm.REG_R1, 0)
p.Reg = arm.REGSP
p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.Duffzero
p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr))
} else {
- p = pp.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0, 4+frame+lo, obj.TYPE_REG, arm.REG_R1, 0)
+ p = pp.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0, 4+off, obj.TYPE_REG, arm.REG_R1, 0)
p.Reg = arm.REGSP
p = pp.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, arm.REG_R2, 0)
p.Reg = arm.REG_R1
arch.REGSP = arm64.REGSP
arch.MAXWIDTH = 1 << 50
- arch.Defframe = defframe
+ arch.PadFrame = padframe
+ arch.ZeroRange = zerorange
arch.Ginsnop = ginsnop
arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
"cmd/internal/objabi"
)
-func defframe(pp *gc.Progs, fn *gc.Node, sz int64) {
- // fill in argument size, stack size
- pp.Text.To.Type = obj.TYPE_TEXTSIZE
-
- pp.Text.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
- frame := uint32(gc.Rnd(sz, int64(gc.Widthreg)))
+var darwin = objabi.GOOS == "darwin"
+func padframe(frame int64) int64 {
// arm64 requires that the frame size (not counting saved LR)
// be empty or be 8 mod 16. If not, pad it.
if frame != 0 && frame%16 != 8 {
frame += 8
}
-
- pp.Text.To.Offset = int64(frame)
-
- // insert code to zero ambiguously live variables
- // so that the garbage collector only sees initialized values
- // when it looks for pointers.
- p := pp.Text
-
- hi := int64(0)
- lo := hi
-
- // iterate through declarations - they are sorted in decreasing xoffset order.
- for _, n := range fn.Func.Dcl {
- if !n.Name.Needzero() {
- continue
- }
- if n.Class != gc.PAUTO {
- gc.Fatalf("needzero class %d", n.Class)
- }
- if n.Type.Width%int64(gc.Widthptr) != 0 || n.Xoffset%int64(gc.Widthptr) != 0 || n.Type.Width == 0 {
- gc.Fatalf("var %L has size %d offset %d", n, int(n.Type.Width), int(n.Xoffset))
- }
-
- if lo != hi && n.Xoffset+n.Type.Width >= lo-int64(2*gc.Widthreg) {
- // merge with range we already have
- lo = n.Xoffset
-
- continue
- }
-
- // zero old range
- p = zerorange(pp, p, int64(frame), lo, hi)
-
- // set new range
- hi = n.Xoffset + n.Type.Width
-
- lo = n.Xoffset
- }
-
- // zero final range
- zerorange(pp, p, int64(frame), lo, hi)
+ return frame
}
-var darwin = objabi.GOOS == "darwin"
-
-func zerorange(pp *gc.Progs, p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
- cnt := hi - lo
+func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
if cnt == 0 {
return p
}
if cnt < int64(4*gc.Widthptr) {
for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
- p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+frame+lo+i)
+ p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGSP, 8+off+i)
}
} else if cnt <= int64(128*gc.Widthptr) && !darwin { // darwin ld64 cannot handle BR26 reloc with non-zero addend
p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REGRT1, 0)
- p = pp.Appendpp(p, arm64.AADD, obj.TYPE_CONST, 0, 8+frame+lo-8, obj.TYPE_REG, arm64.REGRT1, 0)
+ p = pp.Appendpp(p, arm64.AADD, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, arm64.REGRT1, 0)
p.Reg = arm64.REGRT1
p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.Duffzero
p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr))
} else {
- p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0, 8+frame+lo-8, obj.TYPE_REG, arm64.REGTMP, 0)
+ p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, arm64.REGTMP, 0)
p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REGRT1, 0)
p = pp.Appendpp(p, arm64.AADD, obj.TYPE_REG, arm64.REGTMP, 0, obj.TYPE_REG, arm64.REGRT1, 0)
p.Reg = arm64.REGRT1
MAXWIDTH int64
Use387 bool // should 386 backend use 387 FP instructions instead of sse2.
- Defframe func(*Progs, *Node, int64)
- Ginsnop func(*Progs)
+ PadFrame func(int64) int64
+ ZeroRange func(*Progs, *obj.Prog, int64, int64, *uint32) *obj.Prog
+ Ginsnop func(*Progs)
// SSAMarkMoves marks any MOVXconst ops that need to avoid clobbering flags.
SSAMarkMoves func(*SSAGenState, *ssa.Block)
}
}
- // Add frame prologue. Zero ambiguously live variables.
- thearch.Defframe(s.pp, e.curfn, e.stksize+s.maxarg)
+ defframe(&s, e)
if Debug['f'] != 0 {
frame(0)
}
f.HTMLWriter = nil
}
+func defframe(s *SSAGenState, e *ssafn) {
+ pp := s.pp
+
+ frame := Rnd(s.maxarg+e.stksize, int64(Widthreg))
+ if thearch.PadFrame != nil {
+ frame = thearch.PadFrame(frame)
+ }
+
+ // Fill in argument and frame size.
+ pp.Text.To.Type = obj.TYPE_TEXTSIZE
+ pp.Text.To.Val = int32(Rnd(e.curfn.Type.ArgWidth(), int64(Widthreg)))
+ pp.Text.To.Offset = frame
+
+ // Insert code to zero ambiguously live variables so that the
+ // garbage collector only sees initialized values when it
+ // looks for pointers.
+ p := pp.Text
+ var lo, hi int64
+
+ // Opaque state for backend to use. Current backends use it to
+ // keep track of which helper registers have been zeroed.
+ var state uint32
+
+ // Iterate through declarations. They are sorted in decreasing Xoffset order.
+ for _, n := range e.curfn.Func.Dcl {
+ if !n.Name.Needzero() {
+ continue
+ }
+ if n.Class != PAUTO {
+ Fatalf("needzero class %d", n.Class)
+ }
+ if n.Type.Size()%int64(Widthptr) != 0 || n.Xoffset%int64(Widthptr) != 0 || n.Type.Size() == 0 {
+ Fatalf("var %L has size %d offset %d", n, n.Type.Size(), n.Xoffset)
+ }
+
+ if lo != hi && n.Xoffset+n.Type.Size() >= lo-int64(2*Widthreg) {
+ // Merge with range we already have.
+ lo = n.Xoffset
+ continue
+ }
+
+ // Zero old range
+ p = thearch.ZeroRange(pp, p, frame+lo, hi-lo, &state)
+
+ // Set new range.
+ lo = n.Xoffset
+ hi = lo + n.Type.Size()
+ }
+
+ // Zero final range.
+ thearch.ZeroRange(pp, p, frame+lo, hi-lo, &state)
+}
+
type FloatingEQNEJump struct {
Jump obj.As
Index int
}
arch.REGSP = mips.REGSP
arch.MAXWIDTH = (1 << 31) - 1
- arch.Defframe = defframe
+ arch.ZeroRange = zerorange
arch.Ginsnop = ginsnop
arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
arch.SSAGenValue = ssaGenValue
"cmd/internal/obj/mips"
)
-func defframe(pp *gc.Progs, fn *gc.Node, sz int64) {
- // fill in argument size, stack size
- pp.Text.To.Type = obj.TYPE_TEXTSIZE
-
- pp.Text.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
- frame := uint32(gc.Rnd(sz, int64(gc.Widthreg)))
- pp.Text.To.Offset = int64(frame)
-
- // insert code to zero ambiguously live variables
- // so that the garbage collector only sees initialized values
- // when it looks for pointers.
- p := pp.Text
-
- hi := int64(0)
- lo := hi
-
- // iterate through declarations - they are sorted in decreasing xoffset order.
- for _, n := range fn.Func.Dcl {
- if !n.Name.Needzero() {
- continue
- }
- if n.Class != gc.PAUTO {
- gc.Fatalf("needzero class %d", n.Class)
- }
- if n.Type.Width%int64(gc.Widthptr) != 0 || n.Xoffset%int64(gc.Widthptr) != 0 || n.Type.Width == 0 {
- gc.Fatalf("var %L has size %d offset %d", n, int(n.Type.Width), int(n.Xoffset))
- }
-
- if lo != hi && n.Xoffset+n.Type.Width >= lo-int64(2*gc.Widthreg) {
- // merge with range we already have
- lo = n.Xoffset
-
- continue
- }
-
- // zero old range
- p = zerorange(pp, p, int64(frame), lo, hi)
-
- // set new range
- hi = n.Xoffset + n.Type.Width
-
- lo = n.Xoffset
- }
-
- // zero final range
- zerorange(pp, p, int64(frame), lo, hi)
-}
-
// TODO(mips): implement DUFFZERO
-func zerorange(pp *gc.Progs, p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
+func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
- cnt := hi - lo
if cnt == 0 {
return p
}
if cnt < int64(4*gc.Widthptr) {
for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
- p = pp.Appendpp(p, mips.AMOVW, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, gc.Ctxt.FixedFrameSize()+frame+lo+i)
+ p = pp.Appendpp(p, mips.AMOVW, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, gc.Ctxt.FixedFrameSize()+off+i)
}
} else {
//fmt.Printf("zerorange frame:%v, lo: %v, hi:%v \n", frame ,lo, hi)
// MOVW R0, (Widthptr)r1
// ADD $Widthptr, r1
// BNE r1, r2, loop
- p = pp.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, gc.Ctxt.FixedFrameSize()+frame+lo-4, obj.TYPE_REG, mips.REGRT1, 0)
+ p = pp.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, gc.Ctxt.FixedFrameSize()+off-4, obj.TYPE_REG, mips.REGRT1, 0)
p.Reg = mips.REGSP
p = pp.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, mips.REGRT2, 0)
p.Reg = mips.REGRT1
arch.REGSP = mips.REGSP
arch.MAXWIDTH = 1 << 50
- arch.Defframe = defframe
+ arch.ZeroRange = zerorange
arch.Ginsnop = ginsnop
arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
"cmd/internal/obj/mips"
)
-func defframe(pp *gc.Progs, fn *gc.Node, sz int64) {
- // fill in argument size, stack size
- pp.Text.To.Type = obj.TYPE_TEXTSIZE
-
- pp.Text.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
- frame := uint32(gc.Rnd(sz, int64(gc.Widthreg)))
- pp.Text.To.Offset = int64(frame)
-
- // insert code to zero ambiguously live variables
- // so that the garbage collector only sees initialized values
- // when it looks for pointers.
- p := pp.Text
-
- hi := int64(0)
- lo := hi
-
- // iterate through declarations - they are sorted in decreasing xoffset order.
- for _, n := range fn.Func.Dcl {
- if !n.Name.Needzero() {
- continue
- }
- if n.Class != gc.PAUTO {
- gc.Fatalf("needzero class %d", n.Class)
- }
- if n.Type.Width%int64(gc.Widthptr) != 0 || n.Xoffset%int64(gc.Widthptr) != 0 || n.Type.Width == 0 {
- gc.Fatalf("var %L has size %d offset %d", n, int(n.Type.Width), int(n.Xoffset))
- }
-
- if lo != hi && n.Xoffset+n.Type.Width >= lo-int64(2*gc.Widthreg) {
- // merge with range we already have
- lo = n.Xoffset
-
- continue
- }
-
- // zero old range
- p = zerorange(pp, p, int64(frame), lo, hi)
-
- // set new range
- hi = n.Xoffset + n.Type.Width
-
- lo = n.Xoffset
- }
-
- // zero final range
- zerorange(pp, p, int64(frame), lo, hi)
-}
-
-func zerorange(pp *gc.Progs, p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
- cnt := hi - lo
+func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
if cnt == 0 {
return p
}
if cnt < int64(4*gc.Widthptr) {
for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
- p = pp.Appendpp(p, mips.AMOVV, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, 8+frame+lo+i)
+ p = pp.Appendpp(p, mips.AMOVV, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGSP, 8+off+i)
}
} else if cnt <= int64(128*gc.Widthptr) {
- p = pp.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, 8+frame+lo-8, obj.TYPE_REG, mips.REGRT1, 0)
+ p = pp.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, mips.REGRT1, 0)
p.Reg = mips.REGSP
p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
p.To.Name = obj.NAME_EXTERN
// MOVV R0, (Widthptr)r1
// ADDV $Widthptr, r1
// BNE r1, r2, loop
- p = pp.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, 8+frame+lo-8, obj.TYPE_REG, mips.REGRT1, 0)
+ p = pp.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, 8+off-8, obj.TYPE_REG, mips.REGRT1, 0)
p.Reg = mips.REGSP
p = pp.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, mips.REGRT2, 0)
p.Reg = mips.REGRT1
arch.REGSP = ppc64.REGSP
arch.MAXWIDTH = 1 << 50
- arch.Defframe = defframe
+ arch.ZeroRange = zerorange
arch.Ginsnop = ginsnop2
arch.SSAMarkMoves = ssaMarkMoves
"cmd/internal/obj/ppc64"
)
-func defframe(pp *gc.Progs, fn *gc.Node, sz int64) {
- // fill in argument size, stack size
- pp.Text.To.Type = obj.TYPE_TEXTSIZE
-
- pp.Text.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
- frame := uint32(gc.Rnd(sz, int64(gc.Widthreg)))
- pp.Text.To.Offset = int64(frame)
-
- // insert code to zero ambiguously live variables
- // so that the garbage collector only sees initialized values
- // when it looks for pointers.
- p := pp.Text
-
- hi := int64(0)
- lo := hi
-
- // iterate through declarations - they are sorted in decreasing xoffset order.
- for _, n := range fn.Func.Dcl {
- if !n.Name.Needzero() {
- continue
- }
- if n.Class != gc.PAUTO {
- gc.Fatalf("needzero class %d", n.Class)
- }
- if n.Type.Width%int64(gc.Widthptr) != 0 || n.Xoffset%int64(gc.Widthptr) != 0 || n.Type.Width == 0 {
- gc.Fatalf("var %L has size %d offset %d", n, int(n.Type.Width), int(n.Xoffset))
- }
-
- if lo != hi && n.Xoffset+n.Type.Width >= lo-int64(2*gc.Widthreg) {
- // merge with range we already have
- lo = n.Xoffset
-
- continue
- }
-
- // zero old range
- p = zerorange(pp, p, int64(frame), lo, hi)
-
- // set new range
- hi = n.Xoffset + n.Type.Width
-
- lo = n.Xoffset
- }
-
- // zero final range
- zerorange(pp, p, int64(frame), lo, hi)
-}
-
-func zerorange(pp *gc.Progs, p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
- cnt := hi - lo
+func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
if cnt == 0 {
return p
}
if cnt < int64(4*gc.Widthptr) {
for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
- p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGSP, gc.Ctxt.FixedFrameSize()+frame+lo+i)
+ p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGSP, gc.Ctxt.FixedFrameSize()+off+i)
}
} else if cnt <= int64(128*gc.Widthptr) {
- p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_CONST, 0, gc.Ctxt.FixedFrameSize()+frame+lo-8, obj.TYPE_REG, ppc64.REGRT1, 0)
+ p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_CONST, 0, gc.Ctxt.FixedFrameSize()+off-8, obj.TYPE_REG, ppc64.REGRT1, 0)
p.Reg = ppc64.REGSP
p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.Duffzero
p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr))
} else {
- p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, gc.Ctxt.FixedFrameSize()+frame+lo-8, obj.TYPE_REG, ppc64.REGTMP, 0)
+ p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, gc.Ctxt.FixedFrameSize()+off-8, obj.TYPE_REG, ppc64.REGTMP, 0)
p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT1, 0)
p.Reg = ppc64.REGSP
p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, ppc64.REGTMP, 0)
arch.REGSP = s390x.REGSP
arch.MAXWIDTH = 1 << 50
- arch.Defframe = defframe
+ arch.ZeroRange = zerorange
arch.Ginsnop = ginsnop
arch.SSAMarkMoves = ssaMarkMoves
// Must be between 256 and 4096.
const clearLoopCutoff = 1024
-func defframe(pp *gc.Progs, fn *gc.Node, sz int64) {
- // fill in argument size, stack size
- pp.Text.To.Type = obj.TYPE_TEXTSIZE
-
- pp.Text.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
- frame := uint32(gc.Rnd(sz, int64(gc.Widthreg)))
- pp.Text.To.Offset = int64(frame)
-
- // insert code to zero ambiguously live variables
- // so that the garbage collector only sees initialized values
- // when it looks for pointers.
- p := pp.Text
-
- hi := int64(0)
- lo := hi
-
- // iterate through declarations - they are sorted in decreasing xoffset order.
- for _, n := range fn.Func.Dcl {
- if !n.Name.Needzero() {
- continue
- }
- if n.Class != gc.PAUTO {
- gc.Fatalf("needzero class %d", n.Class)
- }
- if n.Type.Width%int64(gc.Widthptr) != 0 || n.Xoffset%int64(gc.Widthptr) != 0 || n.Type.Width == 0 {
- gc.Fatalf("var %L has size %d offset %d", n, int(n.Type.Width), int(n.Xoffset))
- }
-
- if lo != hi && n.Xoffset+n.Type.Width >= lo-int64(2*gc.Widthreg) {
- // merge with range we already have
- lo = n.Xoffset
-
- continue
- }
-
- // zero old range
- p = zerorange(pp, p, int64(frame), lo, hi)
-
- // set new range
- hi = n.Xoffset + n.Type.Width
-
- lo = n.Xoffset
- }
-
- // zero final range
- zerorange(pp, p, int64(frame), lo, hi)
-}
-
// zerorange clears the stack in the given range.
-func zerorange(pp *gc.Progs, p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
- cnt := hi - lo
+func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog {
if cnt == 0 {
return p
}
// Adjust the frame to account for LR.
- frame += gc.Ctxt.FixedFrameSize()
- offset := frame + lo
+ off += gc.Ctxt.FixedFrameSize()
reg := int16(s390x.REGSP)
- // If the offset cannot fit in a 12-bit unsigned displacement then we
+ // If the off cannot fit in a 12-bit unsigned displacement then we
// need to create a copy of the stack pointer that we can adjust.
// We also need to do this if we are going to loop.
- if offset < 0 || offset > 4096-clearLoopCutoff || cnt > clearLoopCutoff {
- p = pp.Appendpp(p, s390x.AADD, obj.TYPE_CONST, 0, offset, obj.TYPE_REG, s390x.REGRT1, 0)
+ if off < 0 || off > 4096-clearLoopCutoff || cnt > clearLoopCutoff {
+ p = pp.Appendpp(p, s390x.AADD, obj.TYPE_CONST, 0, off, obj.TYPE_REG, s390x.REGRT1, 0)
p.Reg = int16(s390x.REGSP)
reg = s390x.REGRT1
- offset = 0
+ off = 0
}
// Generate a loop of large clears.
if cnt > clearLoopCutoff {
n := cnt - (cnt % 256)
end := int16(s390x.REGRT2)
- p = pp.Appendpp(p, s390x.AADD, obj.TYPE_CONST, 0, offset+n, obj.TYPE_REG, end, 0)
+ p = pp.Appendpp(p, s390x.AADD, obj.TYPE_CONST, 0, off+n, obj.TYPE_REG, end, 0)
p.Reg = reg
- p = pp.Appendpp(p, s390x.AXC, obj.TYPE_MEM, reg, offset, obj.TYPE_MEM, reg, offset)
+ p = pp.Appendpp(p, s390x.AXC, obj.TYPE_MEM, reg, off, obj.TYPE_MEM, reg, off)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = 256
case 2:
ins = s390x.AMOVH
}
- p = pp.Appendpp(p, ins, obj.TYPE_CONST, 0, 0, obj.TYPE_MEM, reg, offset)
+ p = pp.Appendpp(p, ins, obj.TYPE_CONST, 0, 0, obj.TYPE_MEM, reg, off)
// Handle clears that would require multiple move instructions with XC.
default:
- p = pp.Appendpp(p, s390x.AXC, obj.TYPE_MEM, reg, offset, obj.TYPE_MEM, reg, offset)
+ p = pp.Appendpp(p, s390x.AXC, obj.TYPE_MEM, reg, off, obj.TYPE_MEM, reg, off)
p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST
p.From3.Offset = n
}
cnt -= n
- offset += n
+ off += n
}
return p
}
arch.MAXWIDTH = (1 << 32) - 1
- arch.Defframe = defframe
+ arch.ZeroRange = zerorange
arch.Ginsnop = ginsnop
arch.SSAMarkMoves = ssaMarkMoves
"cmd/internal/obj/x86"
)
-func defframe(pp *gc.Progs, fn *gc.Node, sz int64) {
- // fill in argument size, stack size
- pp.Text.To.Type = obj.TYPE_TEXTSIZE
-
- pp.Text.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
- frame := uint32(gc.Rnd(sz, int64(gc.Widthreg)))
- pp.Text.To.Offset = int64(frame)
-
- // insert code to zero ambiguously live variables
- // so that the garbage collector only sees initialized values
- // when it looks for pointers.
- p := pp.Text
-
- hi := int64(0)
- lo := hi
- ax := uint32(0)
- for _, n := range fn.Func.Dcl {
- if !n.Name.Needzero() {
- continue
- }
- if n.Class != gc.PAUTO {
- gc.Fatalf("needzero class %d", n.Class)
- }
- if n.Type.Width%int64(gc.Widthptr) != 0 || n.Xoffset%int64(gc.Widthptr) != 0 || n.Type.Width == 0 {
- gc.Fatalf("var %L has size %d offset %d", n, int(n.Type.Width), int(n.Xoffset))
- }
- if lo != hi && n.Xoffset+n.Type.Width >= lo-int64(2*gc.Widthptr) {
- // merge with range we already have
- lo = n.Xoffset
-
- continue
- }
-
- // zero old range
- p = zerorange(pp, p, int64(frame), lo, hi, &ax)
-
- // set new range
- hi = n.Xoffset + n.Type.Width
-
- lo = n.Xoffset
- }
-
- // zero final range
- zerorange(pp, p, int64(frame), lo, hi, &ax)
-}
-
-func zerorange(pp *gc.Progs, p *obj.Prog, frame int64, lo int64, hi int64, ax *uint32) *obj.Prog {
- cnt := hi - lo
+func zerorange(pp *gc.Progs, p *obj.Prog, off, cnt int64, ax *uint32) *obj.Prog {
if cnt == 0 {
return p
}
if cnt <= int64(4*gc.Widthreg) {
for i := int64(0); i < cnt; i += int64(gc.Widthreg) {
- p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, frame+lo+i)
+ p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, off+i)
}
} else if !gc.Nacl && cnt <= int64(128*gc.Widthreg) {
- p = pp.Appendpp(p, x86.ALEAL, obj.TYPE_MEM, x86.REG_SP, frame+lo, obj.TYPE_REG, x86.REG_DI, 0)
+ p = pp.Appendpp(p, x86.ALEAL, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_ADDR, 0, 1*(128-cnt/int64(gc.Widthreg)))
p.To.Sym = gc.Duffzero
} else {
p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_CONST, 0, cnt/int64(gc.Widthreg), obj.TYPE_REG, x86.REG_CX, 0)
- p = pp.Appendpp(p, x86.ALEAL, obj.TYPE_MEM, x86.REG_SP, frame+lo, obj.TYPE_REG, x86.REG_DI, 0)
+ p = pp.Appendpp(p, x86.ALEAL, obj.TYPE_MEM, x86.REG_SP, off, obj.TYPE_REG, x86.REG_DI, 0)
p = pp.Appendpp(p, x86.AREP, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
p = pp.Appendpp(p, x86.ASTOSL, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
}