Commit c3a50ad3 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: eliminate Prog-related globals

Introduce a new type, gc.Progs, to manage
generation of Progs for a function.
Use it to replace globals pc and pcloc.

Passes toolstash-check -all.

Updates #15756

Change-Id: I2206998d7c58fe2a76b620904909f2e1cec8a57d
Reviewed-on: https://go-review.googlesource.com/38418
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: 's avatarMatthew Dempsky <mdempsky@google.com>
parent 27bc723b
...@@ -13,18 +13,18 @@ import ( ...@@ -13,18 +13,18 @@ import (
// no floating point in note handlers on Plan 9 // no floating point in note handlers on Plan 9
var isPlan9 = obj.GOOS == "plan9" var isPlan9 = obj.GOOS == "plan9"
func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { func defframe(pp *gc.Progs, fn *gc.Node, sz int64) {
// fill in argument size, stack size // fill in argument size, stack size
ptxt.To.Type = obj.TYPE_TEXTSIZE pp.Text.To.Type = obj.TYPE_TEXTSIZE
ptxt.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr))) pp.Text.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
frame := uint32(gc.Rnd(sz, int64(gc.Widthreg))) frame := uint32(gc.Rnd(sz, int64(gc.Widthreg)))
ptxt.To.Offset = int64(frame) pp.Text.To.Offset = int64(frame)
// insert code to zero ambiguously live variables // insert code to zero ambiguously live variables
// so that the garbage collector only sees initialized values // so that the garbage collector only sees initialized values
// when it looks for pointers. // when it looks for pointers.
p := ptxt p := pp.Text
hi := int64(0) hi := int64(0)
lo := hi lo := hi
...@@ -51,7 +51,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -51,7 +51,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
} }
// zero old range // zero old range
p = zerorange(p, int64(frame), lo, hi, &ax, &x0) p = zerorange(pp, p, int64(frame), lo, hi, &ax, &x0)
// set new range // set new range
hi = n.Xoffset + n.Type.Width hi = n.Xoffset + n.Type.Width
...@@ -60,7 +60,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -60,7 +60,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
} }
// zero final range // zero final range
zerorange(p, int64(frame), lo, hi, &ax, &x0) zerorange(pp, p, int64(frame), lo, hi, &ax, &x0)
} }
// DUFFZERO consists of repeated blocks of 4 MOVUPSs + ADD, // DUFFZERO consists of repeated blocks of 4 MOVUPSs + ADD,
...@@ -100,7 +100,7 @@ func dzDI(b int64) int64 { ...@@ -100,7 +100,7 @@ func dzDI(b int64) int64 {
return -dzClearStep * (dzBlockLen - tailSteps) return -dzClearStep * (dzBlockLen - tailSteps)
} }
func zerorange(p *obj.Prog, frame int64, lo int64, hi int64, ax *uint32, x0 *uint32) *obj.Prog { func zerorange(pp *gc.Progs, p *obj.Prog, frame int64, lo int64, hi int64, ax *uint32, x0 *uint32) *obj.Prog {
cnt := hi - lo cnt := hi - lo
if cnt == 0 { if cnt == 0 {
return p return p
...@@ -112,65 +112,65 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64, ax *uint32, x0 *uin ...@@ -112,65 +112,65 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64, ax *uint32, x0 *uin
gc.Fatalf("zerorange count not a multiple of widthptr %d", cnt) gc.Fatalf("zerorange count not a multiple of widthptr %d", cnt)
} }
if *ax == 0 { if *ax == 0 {
p = gc.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0) p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
*ax = 1 *ax = 1
} }
p = gc.Appendpp(p, x86.AMOVL, obj.TYPE_REG, x86.REG_AX, 0, obj.TYPE_MEM, x86.REG_SP, frame+lo) 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) lo += int64(gc.Widthptr)
cnt -= int64(gc.Widthptr) cnt -= int64(gc.Widthptr)
} }
if cnt == 8 { if cnt == 8 {
if *ax == 0 { if *ax == 0 {
p = gc.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0) p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
*ax = 1 *ax = 1
} }
p = gc.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, frame+lo)
} else if !isPlan9 && cnt <= int64(8*gc.Widthreg) { } else if !isPlan9 && cnt <= int64(8*gc.Widthreg) {
if *x0 == 0 { if *x0 == 0 {
p = gc.Appendpp(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_REG, x86.REG_X0, 0) p = pp.Appendpp(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_REG, x86.REG_X0, 0)
*x0 = 1 *x0 = 1
} }
for i := int64(0); i < cnt/16; i++ { for i := int64(0); i < cnt/16; i++ {
p = gc.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, frame+lo+i*16)
} }
if cnt%16 != 0 { if cnt%16 != 0 {
p = gc.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, frame+lo+cnt-int64(16))
} }
} else if !gc.Nacl && !isPlan9 && (cnt <= int64(128*gc.Widthreg)) { } else if !gc.Nacl && !isPlan9 && (cnt <= int64(128*gc.Widthreg)) {
if *x0 == 0 { if *x0 == 0 {
p = gc.Appendpp(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_REG, x86.REG_X0, 0) p = pp.Appendpp(p, x86.AXORPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_REG, x86.REG_X0, 0)
*x0 = 1 *x0 = 1
} }
p = gc.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, frame+lo+dzDI(cnt), obj.TYPE_REG, x86.REG_DI, 0)
p = gc.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_ADDR, 0, dzOff(cnt)) p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_ADDR, 0, dzOff(cnt))
p.To.Sym = gc.Duffzero p.To.Sym = gc.Duffzero
if cnt%16 != 0 { if cnt%16 != 0 {
p = gc.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_DI, -int64(8)) p = pp.Appendpp(p, x86.AMOVUPS, obj.TYPE_REG, x86.REG_X0, 0, obj.TYPE_MEM, x86.REG_DI, -int64(8))
} }
} else { } else {
if *ax == 0 { if *ax == 0 {
p = gc.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0) p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
*ax = 1 *ax = 1
} }
p = gc.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, cnt/int64(gc.Widthreg), obj.TYPE_REG, x86.REG_CX, 0) p = pp.Appendpp(p, x86.AMOVQ, obj.TYPE_CONST, 0, cnt/int64(gc.Widthreg), obj.TYPE_REG, x86.REG_CX, 0)
p = gc.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, frame+lo, obj.TYPE_REG, x86.REG_DI, 0)
p = gc.Appendpp(p, x86.AREP, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0) p = pp.Appendpp(p, x86.AREP, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
p = gc.Appendpp(p, x86.ASTOSQ, 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)
} }
return p return p
} }
func ginsnop() { func ginsnop(pp *gc.Progs) {
// This is actually not the x86 NOP anymore, // This is actually not the x86 NOP anymore,
// but at the point where it gets used, AX is dead // but at the point where it gets used, AX is dead
// so it's okay if we lose the high bits. // so it's okay if we lose the high bits.
p := gc.Prog(x86.AXCHGL) p := pp.Prog(x86.AXCHGL)
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = x86.REG_AX p.From.Reg = x86.REG_AX
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
......
...@@ -10,18 +10,18 @@ import ( ...@@ -10,18 +10,18 @@ import (
"cmd/internal/obj/arm" "cmd/internal/obj/arm"
) )
func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { func defframe(pp *gc.Progs, fn *gc.Node, sz int64) {
// fill in argument size, stack size // fill in argument size, stack size
ptxt.To.Type = obj.TYPE_TEXTSIZE pp.Text.To.Type = obj.TYPE_TEXTSIZE
ptxt.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr))) pp.Text.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
frame := uint32(gc.Rnd(sz, int64(gc.Widthreg))) frame := uint32(gc.Rnd(sz, int64(gc.Widthreg)))
ptxt.To.Offset = int64(frame) pp.Text.To.Offset = int64(frame)
// insert code to contain ambiguously live variables // insert code to contain ambiguously live variables
// so that garbage collector only sees initialized values // so that garbage collector only sees initialized values
// when it looks for pointers. // when it looks for pointers.
p := ptxt p := pp.Text
hi := int64(0) hi := int64(0)
lo := hi lo := hi
...@@ -44,7 +44,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -44,7 +44,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
} }
// zero old range // zero old range
p = zerorange(p, int64(frame), lo, hi, &r0) p = zerorange(pp, p, int64(frame), lo, hi, &r0)
// set new range // set new range
hi = n.Xoffset + n.Type.Width hi = n.Xoffset + n.Type.Width
...@@ -53,49 +53,49 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -53,49 +53,49 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
} }
// zero final range // zero final range
zerorange(p, int64(frame), lo, hi, &r0) zerorange(pp, p, int64(frame), lo, hi, &r0)
} }
func zerorange(p *obj.Prog, frame int64, lo int64, hi int64, r0 *uint32) *obj.Prog { func zerorange(pp *gc.Progs, p *obj.Prog, frame int64, lo int64, hi int64, r0 *uint32) *obj.Prog {
cnt := hi - lo cnt := hi - lo
if cnt == 0 { if cnt == 0 {
return p return p
} }
if *r0 == 0 { if *r0 == 0 {
p = gc.Appendpp(p, arm.AMOVW, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, arm.REG_R0, 0) p = pp.Appendpp(p, arm.AMOVW, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, arm.REG_R0, 0)
*r0 = 1 *r0 = 1
} }
if cnt < int64(4*gc.Widthptr) { if cnt < int64(4*gc.Widthptr) {
for i := int64(0); i < cnt; i += int64(gc.Widthptr) { for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
p = gc.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+frame+lo+i)
} }
} else if !gc.Nacl && (cnt <= int64(128*gc.Widthptr)) { } else if !gc.Nacl && (cnt <= int64(128*gc.Widthptr)) {
p = gc.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+frame+lo, obj.TYPE_REG, arm.REG_R1, 0)
p.Reg = arm.REGSP p.Reg = arm.REGSP
p = gc.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0) p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
p.To.Name = obj.NAME_EXTERN p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.Duffzero p.To.Sym = gc.Duffzero
p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr)) p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr))
} else { } else {
p = gc.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+frame+lo, obj.TYPE_REG, arm.REG_R1, 0)
p.Reg = arm.REGSP p.Reg = arm.REGSP
p = gc.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, arm.REG_R2, 0) p = pp.Appendpp(p, arm.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, arm.REG_R2, 0)
p.Reg = arm.REG_R1 p.Reg = arm.REG_R1
p = gc.Appendpp(p, arm.AMOVW, obj.TYPE_REG, arm.REG_R0, 0, obj.TYPE_MEM, arm.REG_R1, 4) p = pp.Appendpp(p, arm.AMOVW, obj.TYPE_REG, arm.REG_R0, 0, obj.TYPE_MEM, arm.REG_R1, 4)
p1 := p p1 := p
p.Scond |= arm.C_PBIT p.Scond |= arm.C_PBIT
p = gc.Appendpp(p, arm.ACMP, obj.TYPE_REG, arm.REG_R1, 0, obj.TYPE_NONE, 0, 0) p = pp.Appendpp(p, arm.ACMP, obj.TYPE_REG, arm.REG_R1, 0, obj.TYPE_NONE, 0, 0)
p.Reg = arm.REG_R2 p.Reg = arm.REG_R2
p = gc.Appendpp(p, arm.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0) p = pp.Appendpp(p, arm.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
gc.Patch(p, p1) gc.Patch(p, p1)
} }
return p return p
} }
func ginsnop() { func ginsnop(pp *gc.Progs) {
p := gc.Prog(arm.AAND) p := pp.Prog(arm.AAND)
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = arm.REG_R0 p.From.Reg = arm.REG_R0
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
......
...@@ -10,11 +10,11 @@ import ( ...@@ -10,11 +10,11 @@ import (
"cmd/internal/obj/arm64" "cmd/internal/obj/arm64"
) )
func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { func defframe(pp *gc.Progs, fn *gc.Node, sz int64) {
// fill in argument size, stack size // fill in argument size, stack size
ptxt.To.Type = obj.TYPE_TEXTSIZE pp.Text.To.Type = obj.TYPE_TEXTSIZE
ptxt.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr))) pp.Text.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
frame := uint32(gc.Rnd(sz, int64(gc.Widthreg))) frame := uint32(gc.Rnd(sz, int64(gc.Widthreg)))
// arm64 requires that the frame size (not counting saved LR) // arm64 requires that the frame size (not counting saved LR)
...@@ -23,12 +23,12 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -23,12 +23,12 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
frame += 8 frame += 8
} }
ptxt.To.Offset = int64(frame) pp.Text.To.Offset = int64(frame)
// insert code to zero ambiguously live variables // insert code to zero ambiguously live variables
// so that the garbage collector only sees initialized values // so that the garbage collector only sees initialized values
// when it looks for pointers. // when it looks for pointers.
p := ptxt p := pp.Text
hi := int64(0) hi := int64(0)
lo := hi lo := hi
...@@ -53,7 +53,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -53,7 +53,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
} }
// zero old range // zero old range
p = zerorange(p, int64(frame), lo, hi) p = zerorange(pp, p, int64(frame), lo, hi)
// set new range // set new range
hi = n.Xoffset + n.Type.Width hi = n.Xoffset + n.Type.Width
...@@ -62,49 +62,49 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -62,49 +62,49 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
} }
// zero final range // zero final range
zerorange(p, int64(frame), lo, hi) zerorange(pp, p, int64(frame), lo, hi)
} }
var darwin = obj.GOOS == "darwin" var darwin = obj.GOOS == "darwin"
func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { func zerorange(pp *gc.Progs, p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
cnt := hi - lo cnt := hi - lo
if cnt == 0 { if cnt == 0 {
return p return p
} }
if cnt < int64(4*gc.Widthptr) { if cnt < int64(4*gc.Widthptr) {
for i := int64(0); i < cnt; i += int64(gc.Widthptr) { for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
p = gc.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+frame+lo+i)
} }
} else if cnt <= int64(128*gc.Widthptr) && !darwin { // darwin ld64 cannot handle BR26 reloc with non-zero addend } else if cnt <= int64(128*gc.Widthptr) && !darwin { // darwin ld64 cannot handle BR26 reloc with non-zero addend
p = gc.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REGRT1, 0) p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REGRT1, 0)
p = gc.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+frame+lo-8, obj.TYPE_REG, arm64.REGRT1, 0)
p.Reg = arm64.REGRT1 p.Reg = arm64.REGRT1
p = gc.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0) p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
p.To.Name = obj.NAME_EXTERN p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.Duffzero p.To.Sym = gc.Duffzero
p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr)) p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr))
} else { } else {
p = gc.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+frame+lo-8, obj.TYPE_REG, arm64.REGTMP, 0)
p = gc.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REGRT1, 0) p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGSP, 0, obj.TYPE_REG, arm64.REGRT1, 0)
p = gc.Appendpp(p, arm64.AADD, obj.TYPE_REG, arm64.REGTMP, 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 p.Reg = arm64.REGRT1
p = gc.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, arm64.REGTMP, 0) p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, arm64.REGTMP, 0)
p = gc.Appendpp(p, arm64.AADD, obj.TYPE_REG, arm64.REGTMP, 0, obj.TYPE_REG, arm64.REGRT2, 0) p = pp.Appendpp(p, arm64.AADD, obj.TYPE_REG, arm64.REGTMP, 0, obj.TYPE_REG, arm64.REGRT2, 0)
p.Reg = arm64.REGRT1 p.Reg = arm64.REGRT1
p = gc.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGRT1, int64(gc.Widthptr)) p = pp.Appendpp(p, arm64.AMOVD, obj.TYPE_REG, arm64.REGZERO, 0, obj.TYPE_MEM, arm64.REGRT1, int64(gc.Widthptr))
p.Scond = arm64.C_XPRE p.Scond = arm64.C_XPRE
p1 := p p1 := p
p = gc.Appendpp(p, arm64.ACMP, obj.TYPE_REG, arm64.REGRT1, 0, obj.TYPE_NONE, 0, 0) p = pp.Appendpp(p, arm64.ACMP, obj.TYPE_REG, arm64.REGRT1, 0, obj.TYPE_NONE, 0, 0)
p.Reg = arm64.REGRT2 p.Reg = arm64.REGRT2
p = gc.Appendpp(p, arm64.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0) p = pp.Appendpp(p, arm64.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
gc.Patch(p, p1) gc.Patch(p, p1)
} }
return p return p
} }
func ginsnop() { func ginsnop(pp *gc.Progs) {
p := gc.Prog(arm64.AHINT) p := pp.Prog(arm64.AHINT)
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
} }
...@@ -1171,7 +1171,6 @@ func funccompile(n *Node) { ...@@ -1171,7 +1171,6 @@ func funccompile(n *Node) {
funcdepth = n.Func.Depth + 1 funcdepth = n.Func.Depth + 1
compile(n) compile(n)
Curfn = nil Curfn = nil
pc = nil
funcdepth = 0 funcdepth = 0
dclcontext = PEXTERN dclcontext = PEXTERN
} }
......
...@@ -285,8 +285,6 @@ var writearchive bool ...@@ -285,8 +285,6 @@ var writearchive bool
var Nacl bool var Nacl bool
var pc *obj.Prog
var nodfp *Node var nodfp *Node
var disable_checknil int var disable_checknil int
...@@ -300,8 +298,8 @@ type Arch struct { ...@@ -300,8 +298,8 @@ type Arch struct {
MAXWIDTH int64 MAXWIDTH int64
Use387 bool // should 386 backend use 387 FP instructions instead of sse2. Use387 bool // should 386 backend use 387 FP instructions instead of sse2.
Defframe func(*obj.Prog, *Node, int64) Defframe func(*Progs, *Node, int64)
Ginsnop func() Ginsnop func(*Progs)
// SSAMarkMoves marks any MOVXconst ops that need to avoid clobbering flags. // SSAMarkMoves marks any MOVXconst ops that need to avoid clobbering flags.
SSAMarkMoves func(*SSAGenState, *ssa.Block) SSAMarkMoves func(*SSAGenState, *ssa.Block)
...@@ -314,8 +312,6 @@ type Arch struct { ...@@ -314,8 +312,6 @@ type Arch struct {
SSAGenBlock func(s *SSAGenState, b, next *ssa.Block) SSAGenBlock func(s *SSAGenState, b, next *ssa.Block)
} }
var pcloc int32
var thearch Arch var thearch Arch
var ( var (
......
...@@ -30,35 +30,66 @@ ...@@ -30,35 +30,66 @@
package gc package gc
import "cmd/internal/obj" import (
"cmd/internal/obj"
"cmd/internal/src"
)
func Prog(as obj.As) *obj.Prog { // Progs accumulates Progs for a function and converts them into machine code.
var p *obj.Prog type Progs struct {
Text *obj.Prog // ATEXT Prog for this function
next *obj.Prog // next Prog
pc int64 // virtual PC; count of Progs
pos src.XPos // position to use for new Progs
}
// newProgs returns a new Progs for fn.
func newProgs(fn *Node) *Progs {
pp := new(Progs)
// prime the pump
pp.next = Ctxt.NewProg()
pp.clearp(pp.next)
pp.pos = fn.Pos
pp.settext(fn)
return pp
}
// Flush converts from pp to machine code.
func (pp *Progs) Flush() {
plist := &obj.Plist{Firstpc: pp.Text}
obj.Flushplist(Ctxt, plist)
// Clear pp to enable GC and avoid abuse.
*pp = Progs{}
}
p = pc // Prog adds a Prog with instruction As to pp.
pc = Ctxt.NewProg() func (pp *Progs) Prog(as obj.As) *obj.Prog {
Clearp(pc) p := pp.next
p.Link = pc pp.next = Ctxt.NewProg()
pp.clearp(pp.next)
p.Link = pp.next
if !lineno.IsKnown() && Debug['K'] != 0 { if !pp.pos.IsKnown() && Debug['K'] != 0 {
Warn("prog: unknown position (line 0)") Warn("prog: unknown position (line 0)")
} }
p.As = as p.As = as
p.Pos = lineno p.Pos = pp.pos
return p return p
} }
func Clearp(p *obj.Prog) { func (pp *Progs) clearp(p *obj.Prog) {
obj.Nopout(p) obj.Nopout(p)
p.As = obj.AEND p.As = obj.AEND
p.Pc = int64(pcloc) p.Pc = pp.pc
pcloc++ pp.pc++
} }
func Appendpp(p *obj.Prog, as obj.As, ftype obj.AddrType, freg int16, foffset int64, ttype obj.AddrType, treg int16, toffset int64) *obj.Prog { func (pp *Progs) Appendpp(p *obj.Prog, as obj.As, ftype obj.AddrType, freg int16, foffset int64, ttype obj.AddrType, treg int16, toffset int64) *obj.Prog {
q := Ctxt.NewProg() q := Ctxt.NewProg()
Clearp(q) pp.clearp(q)
q.As = as q.As = as
q.Pos = p.Pos q.Pos = p.Pos
q.From.Type = ftype q.From.Type = ftype
...@@ -72,6 +103,54 @@ func Appendpp(p *obj.Prog, as obj.As, ftype obj.AddrType, freg int16, foffset in ...@@ -72,6 +103,54 @@ func Appendpp(p *obj.Prog, as obj.As, ftype obj.AddrType, freg int16, foffset in
return q return q
} }
func (pp *Progs) settext(fn *Node) {
if pp.Text != nil {
Fatalf("Progs.settext called twice")
}
ptxt := pp.Prog(obj.ATEXT)
if nam := fn.Func.Nname; !isblank(nam) {
ptxt.From.Type = obj.TYPE_MEM
ptxt.From.Name = obj.NAME_EXTERN
ptxt.From.Sym = Linksym(nam.Sym)
if fn.Func.Pragma&Systemstack != 0 {
ptxt.From.Sym.Set(obj.AttrCFunc, true)
}
}
ptxt.From3 = new(obj.Addr)
if fn.Func.Dupok() {
ptxt.From3.Offset |= obj.DUPOK
}
if fn.Func.Wrapper() {
ptxt.From3.Offset |= obj.WRAPPER
}
if fn.Func.NoFramePointer() {
ptxt.From3.Offset |= obj.NOFRAME
}
if fn.Func.Needctxt() {
ptxt.From3.Offset |= obj.NEEDCTXT
}
if fn.Func.Pragma&Nosplit != 0 {
ptxt.From3.Offset |= obj.NOSPLIT
}
if fn.Func.ReflectMethod() {
ptxt.From3.Offset |= obj.REFLECTMETHOD
}
// Clumsy but important.
// See test/recover.go for test cases and src/reflect/value.go
// for the actual functions being considered.
if myimportpath == "reflect" {
switch fn.Func.Nname.Sym.Name {
case "callReflect", "callMethod":
ptxt.From3.Offset |= obj.WRAPPER
}
}
pp.Text = ptxt
}
func ggloblnod(nam *Node) { func ggloblnod(nam *Node) {
s := Linksym(nam.Sym) s := Linksym(nam.Sym)
s.Gotype = Linksym(ngotype(nam)) s.Gotype = Linksym(ngotype(nam))
......
...@@ -8,7 +8,6 @@ import ( ...@@ -8,7 +8,6 @@ import (
"cmd/compile/internal/ssa" "cmd/compile/internal/ssa"
"cmd/internal/dwarf" "cmd/internal/dwarf"
"cmd/internal/obj" "cmd/internal/obj"
"cmd/internal/src"
"cmd/internal/sys" "cmd/internal/sys"
"fmt" "fmt"
"sort" "sort"
...@@ -18,10 +17,10 @@ import ( ...@@ -18,10 +17,10 @@ import (
var makefuncdatasym_nsym int var makefuncdatasym_nsym int
func makefuncdatasym(nameprefix string, funcdatakind int64) *Sym { func makefuncdatasym(pp *Progs, nameprefix string, funcdatakind int64) *Sym {
sym := lookupN(nameprefix, makefuncdatasym_nsym) sym := lookupN(nameprefix, makefuncdatasym_nsym)
makefuncdatasym_nsym++ makefuncdatasym_nsym++
p := Prog(obj.AFUNCDATA) p := pp.Prog(obj.AFUNCDATA)
Addrconst(&p.From, funcdatakind) Addrconst(&p.From, funcdatakind)
p.To.Type = obj.TYPE_MEM p.To.Type = obj.TYPE_MEM
p.To.Name = obj.NAME_EXTERN p.To.Name = obj.NAME_EXTERN
...@@ -269,10 +268,6 @@ func compile(fn *Node) { ...@@ -269,10 +268,6 @@ func compile(fn *Node) {
assertI2I2 = Sysfunc("assertI2I2") assertI2I2 = Sysfunc("assertI2I2")
} }
defer func(lno src.XPos) {
lineno = lno
}(setlineno(fn))
Curfn = fn Curfn = fn
dowidth(fn.Type) dowidth(fn.Type)
...@@ -309,58 +304,10 @@ func compile(fn *Node) { ...@@ -309,58 +304,10 @@ func compile(fn *Node) {
return return
} }
plist := new(obj.Plist) pp := newProgs(fn)
pc = Ctxt.NewProg() genssa(ssafn, pp)
Clearp(pc) fieldtrack(pp.Text.From.Sym, fn.Func.FieldTrack)
plist.Firstpc = pc pp.Flush()
setlineno(fn)
ptxt := Prog(obj.ATEXT)
if nam := fn.Func.Nname; !isblank(nam) {
ptxt.From.Type = obj.TYPE_MEM
ptxt.From.Name = obj.NAME_EXTERN
ptxt.From.Sym = Linksym(nam.Sym)
if fn.Func.Pragma&Systemstack != 0 {
ptxt.From.Sym.Set(obj.AttrCFunc, true)
}
}
ptxt.From3 = new(obj.Addr)
if fn.Func.Dupok() {
ptxt.From3.Offset |= obj.DUPOK
}
if fn.Func.Wrapper() {
ptxt.From3.Offset |= obj.WRAPPER
}
if fn.Func.NoFramePointer() {
ptxt.From3.Offset |= obj.NOFRAME
}
if fn.Func.Needctxt() {
ptxt.From3.Offset |= obj.NEEDCTXT
}
if fn.Func.Pragma&Nosplit != 0 {
ptxt.From3.Offset |= obj.NOSPLIT
}
if fn.Func.ReflectMethod() {
ptxt.From3.Offset |= obj.REFLECTMETHOD
}
// Clumsy but important.
// See test/recover.go for test cases and src/reflect/value.go
// for the actual functions being considered.
if myimportpath == "reflect" {
if fn.Func.Nname.Sym.Name == "callReflect" || fn.Func.Nname.Sym.Name == "callMethod" {
ptxt.From3.Offset |= obj.WRAPPER
}
}
genssa(ssafn, ptxt)
fieldtrack(ptxt.From.Sym, fn.Func.FieldTrack)
obj.Flushplist(Ctxt, plist) // convert from Prog list to machine code
ptxt = nil // nil to prevent misuse; Prog may have been freed by Flushplist
} }
func debuginfo(fnsym *obj.LSym) []*dwarf.Var { func debuginfo(fnsym *obj.LSym) []*dwarf.Var {
......
...@@ -4234,6 +4234,8 @@ type Branch struct { ...@@ -4234,6 +4234,8 @@ type Branch struct {
// SSAGenState contains state needed during Prog generation. // SSAGenState contains state needed during Prog generation.
type SSAGenState struct { type SSAGenState struct {
pp *Progs
// Branches remembers all the branch instructions we've seen // Branches remembers all the branch instructions we've seen
// and where they would like to go. // and where they would like to go.
Branches []Branch Branches []Branch
...@@ -4255,33 +4257,33 @@ type SSAGenState struct { ...@@ -4255,33 +4257,33 @@ type SSAGenState struct {
// Prog appends a new Prog. // Prog appends a new Prog.
func (s *SSAGenState) Prog(as obj.As) *obj.Prog { func (s *SSAGenState) Prog(as obj.As) *obj.Prog {
return Prog(as) return s.pp.Prog(as)
} }
// Pc returns the current Prog. // Pc returns the current Prog.
func (s *SSAGenState) Pc() *obj.Prog { func (s *SSAGenState) Pc() *obj.Prog {
return pc return s.pp.next
} }
// SetPos sets the current source position. // SetPos sets the current source position.
func (s *SSAGenState) SetPos(pos src.XPos) { func (s *SSAGenState) SetPos(pos src.XPos) {
lineno = pos s.pp.pos = pos
} }
// genssa appends entries to ptxt for each instruction in f. // genssa appends entries to pp for each instruction in f.
func genssa(f *ssa.Func, ptxt *obj.Prog) { func genssa(f *ssa.Func, pp *Progs) {
var s SSAGenState var s SSAGenState
e := f.Frontend().(*ssafn) e := f.Frontend().(*ssafn)
// Generate GC bitmaps. // Generate GC bitmaps.
gcargs := makefuncdatasym("gcargs·", obj.FUNCDATA_ArgsPointerMaps) gcargs := makefuncdatasym(pp, "gcargs·", obj.FUNCDATA_ArgsPointerMaps)
gclocals := makefuncdatasym("gclocals·", obj.FUNCDATA_LocalsPointerMaps) gclocals := makefuncdatasym(pp, "gclocals·", obj.FUNCDATA_LocalsPointerMaps)
s.stackMapIndex = liveness(e, f, gcargs, gclocals) s.stackMapIndex = liveness(e, f, gcargs, gclocals)
// Remember where each block starts. // Remember where each block starts.
s.bstart = make([]*obj.Prog, f.NumBlocks()) s.bstart = make([]*obj.Prog, f.NumBlocks())
s.pp = pp
var valueProgs map[*obj.Prog]*ssa.Value var valueProgs map[*obj.Prog]*ssa.Value
var blockProgs map[*obj.Prog]*ssa.Block var blockProgs map[*obj.Prog]*ssa.Block
var logProgs = e.log var logProgs = e.log
...@@ -4289,7 +4291,7 @@ func genssa(f *ssa.Func, ptxt *obj.Prog) { ...@@ -4289,7 +4291,7 @@ func genssa(f *ssa.Func, ptxt *obj.Prog) {
valueProgs = make(map[*obj.Prog]*ssa.Value, f.NumValues()) valueProgs = make(map[*obj.Prog]*ssa.Value, f.NumValues())
blockProgs = make(map[*obj.Prog]*ssa.Block, f.NumBlocks()) blockProgs = make(map[*obj.Prog]*ssa.Block, f.NumBlocks())
f.Logf("genssa %s\n", f.Name) f.Logf("genssa %s\n", f.Name)
blockProgs[pc] = f.Blocks[0] blockProgs[s.pp.next] = f.Blocks[0]
} }
if thearch.Use387 { if thearch.Use387 {
...@@ -4301,11 +4303,11 @@ func genssa(f *ssa.Func, ptxt *obj.Prog) { ...@@ -4301,11 +4303,11 @@ func genssa(f *ssa.Func, ptxt *obj.Prog) {
// Emit basic blocks // Emit basic blocks
for i, b := range f.Blocks { for i, b := range f.Blocks {
s.bstart[b.ID] = pc s.bstart[b.ID] = s.pp.next
// Emit values in block // Emit values in block
thearch.SSAMarkMoves(&s, b) thearch.SSAMarkMoves(&s, b)
for _, v := range b.Values { for _, v := range b.Values {
x := pc x := s.pp.next
s.SetPos(v.Pos) s.SetPos(v.Pos)
switch v.Op { switch v.Op {
...@@ -4331,7 +4333,7 @@ func genssa(f *ssa.Func, ptxt *obj.Prog) { ...@@ -4331,7 +4333,7 @@ func genssa(f *ssa.Func, ptxt *obj.Prog) {
} }
if logProgs { if logProgs {
for ; x != pc; x = x.Link { for ; x != s.pp.next; x = x.Link {
valueProgs[x] = v valueProgs[x] = v
} }
} }
...@@ -4345,11 +4347,11 @@ func genssa(f *ssa.Func, ptxt *obj.Prog) { ...@@ -4345,11 +4347,11 @@ func genssa(f *ssa.Func, ptxt *obj.Prog) {
// line numbers for otherwise empty blocks. // line numbers for otherwise empty blocks.
next = f.Blocks[i+1] next = f.Blocks[i+1]
} }
x := pc x := s.pp.next
s.SetPos(b.Pos) s.SetPos(b.Pos)
thearch.SSAGenBlock(&s, b, next) thearch.SSAGenBlock(&s, b, next)
if logProgs { if logProgs {
for ; x != pc; x = x.Link { for ; x != s.pp.next; x = x.Link {
blockProgs[x] = b blockProgs[x] = b
} }
} }
...@@ -4361,7 +4363,7 @@ func genssa(f *ssa.Func, ptxt *obj.Prog) { ...@@ -4361,7 +4363,7 @@ func genssa(f *ssa.Func, ptxt *obj.Prog) {
} }
if logProgs { if logProgs {
for p := ptxt; p != nil; p = p.Link { for p := pp.Text; p != nil; p = p.Link {
var s string var s string
if v, ok := valueProgs[p]; ok { if v, ok := valueProgs[p]; ok {
s = v.String() s = v.String()
...@@ -4376,12 +4378,12 @@ func genssa(f *ssa.Func, ptxt *obj.Prog) { ...@@ -4376,12 +4378,12 @@ func genssa(f *ssa.Func, ptxt *obj.Prog) {
// LineHist is defunct now - this code won't do // LineHist is defunct now - this code won't do
// anything. // anything.
// TODO: fix this (ideally without a global variable) // TODO: fix this (ideally without a global variable)
// saved := ptxt.Ctxt.LineHist.PrintFilenameOnly // saved := pp.Text.Ctxt.LineHist.PrintFilenameOnly
// ptxt.Ctxt.LineHist.PrintFilenameOnly = true // pp.Text.Ctxt.LineHist.PrintFilenameOnly = true
var buf bytes.Buffer var buf bytes.Buffer
buf.WriteString("<code>") buf.WriteString("<code>")
buf.WriteString("<dl class=\"ssa-gen\">") buf.WriteString("<dl class=\"ssa-gen\">")
for p := ptxt; p != nil; p = p.Link { for p := pp.Text; p != nil; p = p.Link {
buf.WriteString("<dt class=\"ssa-prog-src\">") buf.WriteString("<dt class=\"ssa-prog-src\">")
if v, ok := valueProgs[p]; ok { if v, ok := valueProgs[p]; ok {
buf.WriteString(v.HTML()) buf.WriteString(v.HTML())
...@@ -4397,12 +4399,12 @@ func genssa(f *ssa.Func, ptxt *obj.Prog) { ...@@ -4397,12 +4399,12 @@ func genssa(f *ssa.Func, ptxt *obj.Prog) {
buf.WriteString("</dl>") buf.WriteString("</dl>")
buf.WriteString("</code>") buf.WriteString("</code>")
f.HTMLWriter.WriteColumn("genssa", buf.String()) f.HTMLWriter.WriteColumn("genssa", buf.String())
// ptxt.Ctxt.LineHist.PrintFilenameOnly = saved // pp.Text.Ctxt.LineHist.PrintFilenameOnly = saved
} }
} }
// Add frame prologue. Zero ambiguously live variables. // Add frame prologue. Zero ambiguously live variables.
thearch.Defframe(ptxt, e.curfn, e.stksize+s.maxarg) thearch.Defframe(s.pp, e.curfn, e.stksize+s.maxarg)
if Debug['f'] != 0 { if Debug['f'] != 0 {
frame(0) frame(0)
} }
...@@ -4638,7 +4640,7 @@ func (s *SSAGenState) Call(v *ssa.Value) *obj.Prog { ...@@ -4638,7 +4640,7 @@ func (s *SSAGenState) Call(v *ssa.Value) *obj.Prog {
// insert an actual hardware NOP that will have the right line number. // insert an actual hardware NOP that will have the right line number.
// This is different from obj.ANOP, which is a virtual no-op // This is different from obj.ANOP, which is a virtual no-op
// that doesn't make it into the instruction stream. // that doesn't make it into the instruction stream.
thearch.Ginsnop() thearch.Ginsnop(s.pp)
} }
p = s.Prog(obj.ACALL) p = s.Prog(obj.ACALL)
......
...@@ -10,18 +10,18 @@ import ( ...@@ -10,18 +10,18 @@ import (
"cmd/internal/obj/mips" "cmd/internal/obj/mips"
) )
func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { func defframe(pp *gc.Progs, fn *gc.Node, sz int64) {
// fill in argument size, stack size // fill in argument size, stack size
ptxt.To.Type = obj.TYPE_TEXTSIZE pp.Text.To.Type = obj.TYPE_TEXTSIZE
ptxt.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr))) pp.Text.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
frame := uint32(gc.Rnd(sz, int64(gc.Widthreg))) frame := uint32(gc.Rnd(sz, int64(gc.Widthreg)))
ptxt.To.Offset = int64(frame) pp.Text.To.Offset = int64(frame)
// insert code to zero ambiguously live variables // insert code to zero ambiguously live variables
// so that the garbage collector only sees initialized values // so that the garbage collector only sees initialized values
// when it looks for pointers. // when it looks for pointers.
p := ptxt p := pp.Text
hi := int64(0) hi := int64(0)
lo := hi lo := hi
...@@ -46,7 +46,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -46,7 +46,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
} }
// zero old range // zero old range
p = zerorange(p, int64(frame), lo, hi) p = zerorange(pp, p, int64(frame), lo, hi)
// set new range // set new range
hi = n.Xoffset + n.Type.Width hi = n.Xoffset + n.Type.Width
...@@ -55,11 +55,11 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -55,11 +55,11 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
} }
// zero final range // zero final range
zerorange(p, int64(frame), lo, hi) zerorange(pp, p, int64(frame), lo, hi)
} }
// TODO(mips): implement DUFFZERO // TODO(mips): implement DUFFZERO
func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { func zerorange(pp *gc.Progs, p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
cnt := hi - lo cnt := hi - lo
if cnt == 0 { if cnt == 0 {
...@@ -67,7 +67,7 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { ...@@ -67,7 +67,7 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
} }
if cnt < int64(4*gc.Widthptr) { if cnt < int64(4*gc.Widthptr) {
for i := int64(0); i < cnt; i += int64(gc.Widthptr) { for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
p = gc.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()+frame+lo+i)
} }
} else { } else {
//fmt.Printf("zerorange frame:%v, lo: %v, hi:%v \n", frame ,lo, hi) //fmt.Printf("zerorange frame:%v, lo: %v, hi:%v \n", frame ,lo, hi)
...@@ -77,14 +77,14 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { ...@@ -77,14 +77,14 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
// MOVW R0, (Widthptr)r1 // MOVW R0, (Widthptr)r1
// ADD $Widthptr, r1 // ADD $Widthptr, r1
// BNE r1, r2, loop // BNE r1, r2, loop
p = gc.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()+frame+lo-4, obj.TYPE_REG, mips.REGRT1, 0)
p.Reg = mips.REGSP p.Reg = mips.REGSP
p = gc.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, mips.REGRT2, 0) p = pp.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, mips.REGRT2, 0)
p.Reg = mips.REGRT1 p.Reg = mips.REGRT1
p = gc.Appendpp(p, mips.AMOVW, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGRT1, int64(gc.Widthptr)) p = pp.Appendpp(p, mips.AMOVW, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGRT1, int64(gc.Widthptr))
p1 := p p1 := p
p = gc.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, int64(gc.Widthptr), obj.TYPE_REG, mips.REGRT1, 0) p = pp.Appendpp(p, mips.AADD, obj.TYPE_CONST, 0, int64(gc.Widthptr), obj.TYPE_REG, mips.REGRT1, 0)
p = gc.Appendpp(p, mips.ABNE, obj.TYPE_REG, mips.REGRT1, 0, obj.TYPE_BRANCH, 0, 0) p = pp.Appendpp(p, mips.ABNE, obj.TYPE_REG, mips.REGRT1, 0, obj.TYPE_BRANCH, 0, 0)
p.Reg = mips.REGRT2 p.Reg = mips.REGRT2
gc.Patch(p, p1) gc.Patch(p, p1)
} }
...@@ -92,8 +92,8 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { ...@@ -92,8 +92,8 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
return p return p
} }
func ginsnop() { func ginsnop(pp *gc.Progs) {
p := gc.Prog(mips.ANOR) p := pp.Prog(mips.ANOR)
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = mips.REG_R0 p.From.Reg = mips.REG_R0
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
......
...@@ -10,18 +10,18 @@ import ( ...@@ -10,18 +10,18 @@ import (
"cmd/internal/obj/mips" "cmd/internal/obj/mips"
) )
func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { func defframe(pp *gc.Progs, fn *gc.Node, sz int64) {
// fill in argument size, stack size // fill in argument size, stack size
ptxt.To.Type = obj.TYPE_TEXTSIZE pp.Text.To.Type = obj.TYPE_TEXTSIZE
ptxt.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr))) pp.Text.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
frame := uint32(gc.Rnd(sz, int64(gc.Widthreg))) frame := uint32(gc.Rnd(sz, int64(gc.Widthreg)))
ptxt.To.Offset = int64(frame) pp.Text.To.Offset = int64(frame)
// insert code to zero ambiguously live variables // insert code to zero ambiguously live variables
// so that the garbage collector only sees initialized values // so that the garbage collector only sees initialized values
// when it looks for pointers. // when it looks for pointers.
p := ptxt p := pp.Text
hi := int64(0) hi := int64(0)
lo := hi lo := hi
...@@ -46,7 +46,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -46,7 +46,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
} }
// zero old range // zero old range
p = zerorange(p, int64(frame), lo, hi) p = zerorange(pp, p, int64(frame), lo, hi)
// set new range // set new range
hi = n.Xoffset + n.Type.Width hi = n.Xoffset + n.Type.Width
...@@ -55,22 +55,22 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -55,22 +55,22 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
} }
// zero final range // zero final range
zerorange(p, int64(frame), lo, hi) zerorange(pp, p, int64(frame), lo, hi)
} }
func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { func zerorange(pp *gc.Progs, p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
cnt := hi - lo cnt := hi - lo
if cnt == 0 { if cnt == 0 {
return p return p
} }
if cnt < int64(4*gc.Widthptr) { if cnt < int64(4*gc.Widthptr) {
for i := int64(0); i < cnt; i += int64(gc.Widthptr) { for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
p = gc.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+frame+lo+i)
} }
} else if cnt <= int64(128*gc.Widthptr) { } else if cnt <= int64(128*gc.Widthptr) {
p = gc.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+frame+lo-8, obj.TYPE_REG, mips.REGRT1, 0)
p.Reg = mips.REGSP p.Reg = mips.REGSP
p = gc.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0) p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
p.To.Name = obj.NAME_EXTERN p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.Duffzero p.To.Sym = gc.Duffzero
p.To.Offset = 8 * (128 - cnt/int64(gc.Widthptr)) p.To.Offset = 8 * (128 - cnt/int64(gc.Widthptr))
...@@ -81,14 +81,14 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { ...@@ -81,14 +81,14 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
// MOVV R0, (Widthptr)r1 // MOVV R0, (Widthptr)r1
// ADDV $Widthptr, r1 // ADDV $Widthptr, r1
// BNE r1, r2, loop // BNE r1, r2, loop
p = gc.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+frame+lo-8, obj.TYPE_REG, mips.REGRT1, 0)
p.Reg = mips.REGSP p.Reg = mips.REGSP
p = gc.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, mips.REGRT2, 0) p = pp.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, mips.REGRT2, 0)
p.Reg = mips.REGRT1 p.Reg = mips.REGRT1
p = gc.Appendpp(p, mips.AMOVV, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGRT1, int64(gc.Widthptr)) p = pp.Appendpp(p, mips.AMOVV, obj.TYPE_REG, mips.REGZERO, 0, obj.TYPE_MEM, mips.REGRT1, int64(gc.Widthptr))
p1 := p p1 := p
p = gc.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, int64(gc.Widthptr), obj.TYPE_REG, mips.REGRT1, 0) p = pp.Appendpp(p, mips.AADDV, obj.TYPE_CONST, 0, int64(gc.Widthptr), obj.TYPE_REG, mips.REGRT1, 0)
p = gc.Appendpp(p, mips.ABNE, obj.TYPE_REG, mips.REGRT1, 0, obj.TYPE_BRANCH, 0, 0) p = pp.Appendpp(p, mips.ABNE, obj.TYPE_REG, mips.REGRT1, 0, obj.TYPE_BRANCH, 0, 0)
p.Reg = mips.REGRT2 p.Reg = mips.REGRT2
gc.Patch(p, p1) gc.Patch(p, p1)
} }
...@@ -96,8 +96,8 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { ...@@ -96,8 +96,8 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
return p return p
} }
func ginsnop() { func ginsnop(pp *gc.Progs) {
p := gc.Prog(mips.ANOR) p := pp.Prog(mips.ANOR)
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = mips.REG_R0 p.From.Reg = mips.REG_R0
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
......
...@@ -10,18 +10,18 @@ import ( ...@@ -10,18 +10,18 @@ import (
"cmd/internal/obj/ppc64" "cmd/internal/obj/ppc64"
) )
func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { func defframe(pp *gc.Progs, fn *gc.Node, sz int64) {
// fill in argument size, stack size // fill in argument size, stack size
ptxt.To.Type = obj.TYPE_TEXTSIZE pp.Text.To.Type = obj.TYPE_TEXTSIZE
ptxt.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr))) pp.Text.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
frame := uint32(gc.Rnd(sz, int64(gc.Widthreg))) frame := uint32(gc.Rnd(sz, int64(gc.Widthreg)))
ptxt.To.Offset = int64(frame) pp.Text.To.Offset = int64(frame)
// insert code to zero ambiguously live variables // insert code to zero ambiguously live variables
// so that the garbage collector only sees initialized values // so that the garbage collector only sees initialized values
// when it looks for pointers. // when it looks for pointers.
p := ptxt p := pp.Text
hi := int64(0) hi := int64(0)
lo := hi lo := hi
...@@ -46,7 +46,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -46,7 +46,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
} }
// zero old range // zero old range
p = zerorange(p, int64(frame), lo, hi) p = zerorange(pp, p, int64(frame), lo, hi)
// set new range // set new range
hi = n.Xoffset + n.Type.Width hi = n.Xoffset + n.Type.Width
...@@ -55,51 +55,51 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -55,51 +55,51 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
} }
// zero final range // zero final range
zerorange(p, int64(frame), lo, hi) zerorange(pp, p, int64(frame), lo, hi)
} }
func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { func zerorange(pp *gc.Progs, p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
cnt := hi - lo cnt := hi - lo
if cnt == 0 { if cnt == 0 {
return p return p
} }
if cnt < int64(4*gc.Widthptr) { if cnt < int64(4*gc.Widthptr) {
for i := int64(0); i < cnt; i += int64(gc.Widthptr) { for i := int64(0); i < cnt; i += int64(gc.Widthptr) {
p = gc.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()+frame+lo+i)
} }
} else if cnt <= int64(128*gc.Widthptr) { } else if cnt <= int64(128*gc.Widthptr) {
p = gc.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()+frame+lo-8, obj.TYPE_REG, ppc64.REGRT1, 0)
p.Reg = ppc64.REGSP p.Reg = ppc64.REGSP
p = gc.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0) p = pp.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
p.To.Name = obj.NAME_EXTERN p.To.Name = obj.NAME_EXTERN
p.To.Sym = gc.Duffzero p.To.Sym = gc.Duffzero
p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr)) p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr))
} else { } else {
p = gc.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()+frame+lo-8, obj.TYPE_REG, ppc64.REGTMP, 0)
p = gc.Appendpp(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT1, 0) p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT1, 0)
p.Reg = ppc64.REGSP p.Reg = ppc64.REGSP
p = gc.Appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, ppc64.REGTMP, 0) p = pp.Appendpp(p, ppc64.AMOVD, obj.TYPE_CONST, 0, cnt, obj.TYPE_REG, ppc64.REGTMP, 0)
p = gc.Appendpp(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT2, 0) p = pp.Appendpp(p, ppc64.AADD, obj.TYPE_REG, ppc64.REGTMP, 0, obj.TYPE_REG, ppc64.REGRT2, 0)
p.Reg = ppc64.REGRT1 p.Reg = ppc64.REGRT1
p = gc.Appendpp(p, ppc64.AMOVDU, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGRT1, int64(gc.Widthptr)) p = pp.Appendpp(p, ppc64.AMOVDU, obj.TYPE_REG, ppc64.REGZERO, 0, obj.TYPE_MEM, ppc64.REGRT1, int64(gc.Widthptr))
p1 := p p1 := p
p = gc.Appendpp(p, ppc64.ACMP, obj.TYPE_REG, ppc64.REGRT1, 0, obj.TYPE_REG, ppc64.REGRT2, 0) p = pp.Appendpp(p, ppc64.ACMP, obj.TYPE_REG, ppc64.REGRT1, 0, obj.TYPE_REG, ppc64.REGRT2, 0)
p = gc.Appendpp(p, ppc64.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0) p = pp.Appendpp(p, ppc64.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
gc.Patch(p, p1) gc.Patch(p, p1)
} }
return p return p
} }
func ginsnop() { func ginsnop(pp *gc.Progs) {
p := gc.Prog(ppc64.AOR) p := pp.Prog(ppc64.AOR)
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = ppc64.REG_R0 p.From.Reg = ppc64.REG_R0
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = ppc64.REG_R0 p.To.Reg = ppc64.REG_R0
} }
func ginsnop2() { func ginsnop2(pp *gc.Progs) {
// PPC64 is unusual because TWO nops are required // PPC64 is unusual because TWO nops are required
// (see gc/cgen.go, gc/plive.go -- copy of comment below) // (see gc/cgen.go, gc/plive.go -- copy of comment below)
// //
...@@ -112,15 +112,15 @@ func ginsnop2() { ...@@ -112,15 +112,15 @@ func ginsnop2() {
// so that the same number of instructions are used // so that the same number of instructions are used
// on ppc64 in both shared and non-shared modes. // on ppc64 in both shared and non-shared modes.
ginsnop() ginsnop(pp)
if gc.Ctxt.Flag_shared { if gc.Ctxt.Flag_shared {
p := gc.Prog(ppc64.AMOVD) p := pp.Prog(ppc64.AMOVD)
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
p.From.Offset = 24 p.From.Offset = 24
p.From.Reg = ppc64.REGSP p.From.Reg = ppc64.REGSP
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = ppc64.REG_R2 p.To.Reg = ppc64.REG_R2
} else { } else {
ginsnop() ginsnop(pp)
} }
} }
...@@ -16,18 +16,18 @@ import ( ...@@ -16,18 +16,18 @@ import (
// Must be between 256 and 4096. // Must be between 256 and 4096.
const clearLoopCutoff = 1024 const clearLoopCutoff = 1024
func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { func defframe(pp *gc.Progs, fn *gc.Node, sz int64) {
// fill in argument size, stack size // fill in argument size, stack size
ptxt.To.Type = obj.TYPE_TEXTSIZE pp.Text.To.Type = obj.TYPE_TEXTSIZE
ptxt.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr))) pp.Text.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
frame := uint32(gc.Rnd(sz, int64(gc.Widthreg))) frame := uint32(gc.Rnd(sz, int64(gc.Widthreg)))
ptxt.To.Offset = int64(frame) pp.Text.To.Offset = int64(frame)
// insert code to zero ambiguously live variables // insert code to zero ambiguously live variables
// so that the garbage collector only sees initialized values // so that the garbage collector only sees initialized values
// when it looks for pointers. // when it looks for pointers.
p := ptxt p := pp.Text
hi := int64(0) hi := int64(0)
lo := hi lo := hi
...@@ -52,7 +52,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -52,7 +52,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
} }
// zero old range // zero old range
p = zerorange(p, int64(frame), lo, hi) p = zerorange(pp, p, int64(frame), lo, hi)
// set new range // set new range
hi = n.Xoffset + n.Type.Width hi = n.Xoffset + n.Type.Width
...@@ -61,11 +61,11 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -61,11 +61,11 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
} }
// zero final range // zero final range
zerorange(p, int64(frame), lo, hi) zerorange(pp, p, int64(frame), lo, hi)
} }
// zerorange clears the stack in the given range. // zerorange clears the stack in the given range.
func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { func zerorange(pp *gc.Progs, p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
cnt := hi - lo cnt := hi - lo
if cnt == 0 { if cnt == 0 {
return p return p
...@@ -80,7 +80,7 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { ...@@ -80,7 +80,7 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
// need to create a copy of the stack pointer that we can adjust. // 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. // We also need to do this if we are going to loop.
if offset < 0 || offset > 4096-clearLoopCutoff || cnt > clearLoopCutoff { if offset < 0 || offset > 4096-clearLoopCutoff || cnt > clearLoopCutoff {
p = gc.Appendpp(p, s390x.AADD, obj.TYPE_CONST, 0, offset, obj.TYPE_REG, s390x.REGRT1, 0) p = pp.Appendpp(p, s390x.AADD, obj.TYPE_CONST, 0, offset, obj.TYPE_REG, s390x.REGRT1, 0)
p.Reg = int16(s390x.REGSP) p.Reg = int16(s390x.REGSP)
reg = s390x.REGRT1 reg = s390x.REGRT1
offset = 0 offset = 0
...@@ -90,16 +90,16 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { ...@@ -90,16 +90,16 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
if cnt > clearLoopCutoff { if cnt > clearLoopCutoff {
n := cnt - (cnt % 256) n := cnt - (cnt % 256)
end := int16(s390x.REGRT2) end := int16(s390x.REGRT2)
p = gc.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, offset+n, obj.TYPE_REG, end, 0)
p.Reg = reg p.Reg = reg
p = gc.Appendpp(p, s390x.AXC, obj.TYPE_MEM, reg, offset, obj.TYPE_MEM, reg, offset) p = pp.Appendpp(p, s390x.AXC, obj.TYPE_MEM, reg, offset, obj.TYPE_MEM, reg, offset)
p.From3 = new(obj.Addr) p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST p.From3.Type = obj.TYPE_CONST
p.From3.Offset = 256 p.From3.Offset = 256
pl := p pl := p
p = gc.Appendpp(p, s390x.AADD, obj.TYPE_CONST, 0, 256, obj.TYPE_REG, reg, 0) p = pp.Appendpp(p, s390x.AADD, obj.TYPE_CONST, 0, 256, obj.TYPE_REG, reg, 0)
p = gc.Appendpp(p, s390x.ACMP, obj.TYPE_REG, reg, 0, obj.TYPE_REG, end, 0) p = pp.Appendpp(p, s390x.ACMP, obj.TYPE_REG, reg, 0, obj.TYPE_REG, end, 0)
p = gc.Appendpp(p, s390x.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0) p = pp.Appendpp(p, s390x.ABNE, obj.TYPE_NONE, 0, 0, obj.TYPE_BRANCH, 0, 0)
gc.Patch(p, pl) gc.Patch(p, pl)
cnt -= n cnt -= n
...@@ -126,11 +126,11 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { ...@@ -126,11 +126,11 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
case 2: case 2:
ins = s390x.AMOVH ins = s390x.AMOVH
} }
p = gc.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, offset)
// Handle clears that would require multiple move instructions with XC. // Handle clears that would require multiple move instructions with XC.
default: default:
p = gc.Appendpp(p, s390x.AXC, obj.TYPE_MEM, reg, offset, obj.TYPE_MEM, reg, offset) p = pp.Appendpp(p, s390x.AXC, obj.TYPE_MEM, reg, offset, obj.TYPE_MEM, reg, offset)
p.From3 = new(obj.Addr) p.From3 = new(obj.Addr)
p.From3.Type = obj.TYPE_CONST p.From3.Type = obj.TYPE_CONST
p.From3.Offset = n p.From3.Offset = n
...@@ -143,8 +143,8 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { ...@@ -143,8 +143,8 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
return p return p
} }
func ginsnop() { func ginsnop(pp *gc.Progs) {
p := gc.Prog(s390x.AOR) p := pp.Prog(s390x.AOR)
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = int16(s390x.REG_R0) p.From.Reg = int16(s390x.REG_R0)
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
......
...@@ -10,18 +10,18 @@ import ( ...@@ -10,18 +10,18 @@ import (
"cmd/internal/obj/x86" "cmd/internal/obj/x86"
) )
func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { func defframe(pp *gc.Progs, fn *gc.Node, sz int64) {
// fill in argument size, stack size // fill in argument size, stack size
ptxt.To.Type = obj.TYPE_TEXTSIZE pp.Text.To.Type = obj.TYPE_TEXTSIZE
ptxt.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr))) pp.Text.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
frame := uint32(gc.Rnd(sz, int64(gc.Widthreg))) frame := uint32(gc.Rnd(sz, int64(gc.Widthreg)))
ptxt.To.Offset = int64(frame) pp.Text.To.Offset = int64(frame)
// insert code to zero ambiguously live variables // insert code to zero ambiguously live variables
// so that the garbage collector only sees initialized values // so that the garbage collector only sees initialized values
// when it looks for pointers. // when it looks for pointers.
p := ptxt p := pp.Text
hi := int64(0) hi := int64(0)
lo := hi lo := hi
...@@ -44,7 +44,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -44,7 +44,7 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
} }
// zero old range // zero old range
p = zerorange(p, int64(frame), lo, hi, &ax) p = zerorange(pp, p, int64(frame), lo, hi, &ax)
// set new range // set new range
hi = n.Xoffset + n.Type.Width hi = n.Xoffset + n.Type.Width
...@@ -53,39 +53,39 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) { ...@@ -53,39 +53,39 @@ func defframe(ptxt *obj.Prog, fn *gc.Node, sz int64) {
} }
// zero final range // zero final range
zerorange(p, int64(frame), lo, hi, &ax) zerorange(pp, p, int64(frame), lo, hi, &ax)
} }
func zerorange(p *obj.Prog, frame int64, lo int64, hi int64, ax *uint32) *obj.Prog { func zerorange(pp *gc.Progs, p *obj.Prog, frame int64, lo int64, hi int64, ax *uint32) *obj.Prog {
cnt := hi - lo cnt := hi - lo
if cnt == 0 { if cnt == 0 {
return p return p
} }
if *ax == 0 { if *ax == 0 {
p = gc.Appendpp(p, x86.AMOVL, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0) p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_CONST, 0, 0, obj.TYPE_REG, x86.REG_AX, 0)
*ax = 1 *ax = 1
} }
if cnt <= int64(4*gc.Widthreg) { if cnt <= int64(4*gc.Widthreg) {
for i := int64(0); i < cnt; i += int64(gc.Widthreg) { for i := int64(0); i < cnt; i += int64(gc.Widthreg) {
p = gc.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, frame+lo+i)
} }
} else if !gc.Nacl && cnt <= int64(128*gc.Widthreg) { } else if !gc.Nacl && cnt <= int64(128*gc.Widthreg) {
p = gc.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, frame+lo, obj.TYPE_REG, x86.REG_DI, 0)
p = gc.Appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_ADDR, 0, 1*(128-cnt/int64(gc.Widthreg))) 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 p.To.Sym = gc.Duffzero
} else { } else {
p = gc.Appendpp(p, x86.AMOVL, obj.TYPE_CONST, 0, cnt/int64(gc.Widthreg), obj.TYPE_REG, x86.REG_CX, 0) p = pp.Appendpp(p, x86.AMOVL, obj.TYPE_CONST, 0, cnt/int64(gc.Widthreg), obj.TYPE_REG, x86.REG_CX, 0)
p = gc.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, frame+lo, obj.TYPE_REG, x86.REG_DI, 0)
p = gc.Appendpp(p, x86.AREP, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0) p = pp.Appendpp(p, x86.AREP, obj.TYPE_NONE, 0, 0, obj.TYPE_NONE, 0, 0)
p = gc.Appendpp(p, x86.ASTOSL, 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)
} }
return p return p
} }
func ginsnop() { func ginsnop(pp *gc.Progs) {
p := gc.Prog(x86.AXCHGL) p := pp.Prog(x86.AXCHGL)
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = x86.REG_AX p.From.Reg = x86.REG_AX
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment