Commit 5b59b32c authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: teach assemblers to accept a Prog allocator

The existing bulk Prog allocator is not concurrency-safe.
To allow for concurrency-safe bulk allocation of Progs,
I want to move Prog allocation and caching upstream,
to the clients of cmd/internal/obj.

This is a preliminary enabling refactoring.
After this CL, instead of calling Ctxt.NewProg
throughout the assemblers, we thread through
a newprog function that returns a new Prog.

That function is set up to be Ctxt.NewProg,
so there are no real changes in this CL;
this CL only establishes the plumbing.

Passes toolstash-check -all.
Negligible compiler performance impact.

Updates #15756

name        old time/op     new time/op     delta
Template        213ms ± 3%      214ms ± 4%    ~     (p=0.574 n=49+47)
Unicode        90.1ms ± 5%     89.9ms ± 4%    ~     (p=0.417 n=50+49)
GoTypes         585ms ± 4%      584ms ± 3%    ~     (p=0.466 n=49+49)
SSA             6.50s ± 3%      6.52s ± 2%    ~     (p=0.251 n=49+49)
Flate           128ms ± 4%      128ms ± 4%    ~     (p=0.673 n=49+50)
GoParser        152ms ± 3%      152ms ± 3%    ~     (p=0.810 n=48+49)
Reflect         372ms ± 4%      372ms ± 5%    ~     (p=0.778 n=49+50)
Tar             113ms ± 5%      111ms ± 4%  -0.98%  (p=0.016 n=50+49)
XML             208ms ± 3%      208ms ± 2%    ~     (p=0.483 n=47+49)
[Geo mean]      285ms           285ms       -0.17%

name        old user-ns/op  new user-ns/op  delta
Template         253M ± 8%       254M ± 9%    ~     (p=0.899 n=50+50)
Unicode          106M ± 9%       106M ±11%    ~     (p=0.642 n=50+50)
GoTypes          736M ± 4%       740M ± 4%    ~     (p=0.121 n=50+49)
SSA             8.82G ± 3%      8.88G ± 2%  +0.65%  (p=0.006 n=49+48)
Flate            147M ± 4%       147M ± 5%    ~     (p=0.844 n=47+48)
GoParser         179M ± 4%       178M ± 6%    ~     (p=0.785 n=50+50)
Reflect          443M ± 6%       441M ± 5%    ~     (p=0.850 n=48+47)
Tar              126M ± 5%       126M ± 5%    ~     (p=0.734 n=50+50)
XML              244M ± 5%       244M ± 5%    ~     (p=0.594 n=49+50)
[Geo mean]       341M            341M       +0.11%

Change-Id: Ice962f61eb3a524c2db00a166cb582c22caa7d68
Reviewed-on: https://go-review.googlesource.com/39633
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarKeith Randall <khr@golang.org>
parent 7e068895
...@@ -279,7 +279,7 @@ var deferreturn *obj.LSym ...@@ -279,7 +279,7 @@ var deferreturn *obj.LSym
// p->pc if extra padding is necessary. // p->pc if extra padding is necessary.
// In rare cases, asmoutnacl might split p into two instructions. // In rare cases, asmoutnacl might split p into two instructions.
// origPC is the PC for this Prog (no padding is taken into account). // origPC is the PC for this Prog (no padding is taken into account).
func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint32) int { func asmoutnacl(ctxt *obj.Link, newprog obj.ProgAlloc, origPC int32, p *obj.Prog, o *Optab, out []uint32) int {
size := int(o.size) size := int(o.size)
// instruction specific // instruction specific
...@@ -406,7 +406,7 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3 ...@@ -406,7 +406,7 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3
// split it into two instructions: // split it into two instructions:
// ADD $-100004, R13 // ADD $-100004, R13
// MOVW R14, 0(R13) // MOVW R14, 0(R13)
q := ctxt.NewProg() q := newprog()
p.Scond &^= C_WBIT p.Scond &^= C_WBIT
*q = *p *q = *p
...@@ -486,7 +486,7 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3 ...@@ -486,7 +486,7 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3
if p.Scond&(C_PBIT|C_WBIT) != 0 { if p.Scond&(C_PBIT|C_WBIT) != 0 {
ctxt.Diag("unsupported instruction (.P/.W): %v", p) ctxt.Diag("unsupported instruction (.P/.W): %v", p)
} }
q := ctxt.NewProg() q := newprog()
*q = *p *q = *p
var a2 *obj.Addr var a2 *obj.Addr
if p.To.Type == obj.TYPE_MEM { if p.To.Type == obj.TYPE_MEM {
...@@ -547,7 +547,7 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3 ...@@ -547,7 +547,7 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3
return size return size
} }
func span5(ctxt *obj.Link, cursym *obj.LSym) { func span5(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
var p *obj.Prog var p *obj.Prog
var op *obj.Prog var op *obj.Prog
...@@ -572,7 +572,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -572,7 +572,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
var o *Optab var o *Optab
for ; p != nil || ctxt.Blitrl != nil; op, p = p, p.Link { for ; p != nil || ctxt.Blitrl != nil; op, p = p, p.Link {
if p == nil { if p == nil {
if checkpool(ctxt, op, 0) { if checkpool(ctxt, newprog, op, 0) {
p = op p = op
continue continue
} }
...@@ -588,7 +588,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -588,7 +588,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
if ctxt.Headtype != obj.Hnacl { if ctxt.Headtype != obj.Hnacl {
m = int(o.size) m = int(o.size)
} else { } else {
m = asmoutnacl(ctxt, c, p, o, nil) m = asmoutnacl(ctxt, newprog, c, p, o, nil)
c = int32(p.Pc) // asmoutnacl might change pc for alignment c = int32(p.Pc) // asmoutnacl might change pc for alignment
o = oplook(ctxt, p) // asmoutnacl might change p in rare cases o = oplook(ctxt, p) // asmoutnacl might change p in rare cases
} }
...@@ -600,7 +600,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -600,7 +600,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
// must check literal pool here in case p generates many instructions // must check literal pool here in case p generates many instructions
if ctxt.Blitrl != nil { if ctxt.Blitrl != nil {
i = m i = m
if checkpool(ctxt, op, i) { if checkpool(ctxt, newprog, op, i) {
p = op p = op
continue continue
} }
...@@ -613,19 +613,19 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -613,19 +613,19 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
switch o.flag & (LFROM | LTO | LPOOL) { switch o.flag & (LFROM | LTO | LPOOL) {
case LFROM: case LFROM:
addpool(ctxt, p, &p.From) addpool(ctxt, newprog, p, &p.From)
case LTO: case LTO:
addpool(ctxt, p, &p.To) addpool(ctxt, newprog, p, &p.To)
case LPOOL: case LPOOL:
if p.Scond&C_SCOND == C_SCOND_NONE { if p.Scond&C_SCOND == C_SCOND_NONE {
flushpool(ctxt, p, 0, 0) flushpool(ctxt, newprog, p, 0, 0)
} }
} }
if p.As == AMOVW && p.To.Type == obj.TYPE_REG && p.To.Reg == REGPC && p.Scond&C_SCOND == C_SCOND_NONE { if p.As == AMOVW && p.To.Type == obj.TYPE_REG && p.To.Reg == REGPC && p.Scond&C_SCOND == C_SCOND_NONE {
flushpool(ctxt, p, 0, 0) flushpool(ctxt, newprog, p, 0, 0)
} }
c += int32(m) c += int32(m)
} }
...@@ -685,7 +685,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -685,7 +685,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
if ctxt.Headtype != obj.Hnacl { if ctxt.Headtype != obj.Hnacl {
m = int(o.size) m = int(o.size)
} else { } else {
m = asmoutnacl(ctxt, c, p, o, nil) m = asmoutnacl(ctxt, newprog, c, p, o, nil)
} }
if p.Pc != int64(opc) { if p.Pc != int64(opc) {
bflag = 1 bflag = 1
...@@ -746,7 +746,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -746,7 +746,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
asmout(ctxt, p, o, out[:]) asmout(ctxt, p, o, out[:])
m = int(o.size) m = int(o.size)
} else { } else {
m = asmoutnacl(ctxt, c, p, o, out[:]) m = asmoutnacl(ctxt, newprog, c, p, o, out[:])
if int64(opc) != p.Pc { if int64(opc) != p.Pc {
ctxt.Diag("asmoutnacl broken: pc changed (%d->%d) in last stage: %v", opc, int32(p.Pc), p) ctxt.Diag("asmoutnacl broken: pc changed (%d->%d) in last stage: %v", opc, int32(p.Pc), p)
} }
...@@ -795,22 +795,22 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -795,22 +795,22 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
* drop the pool now, and branch round it. * drop the pool now, and branch round it.
* this happens only in extended basic blocks that exceed 4k. * this happens only in extended basic blocks that exceed 4k.
*/ */
func checkpool(ctxt *obj.Link, p *obj.Prog, sz int) bool { func checkpool(ctxt *obj.Link, newprog obj.ProgAlloc, p *obj.Prog, sz int) bool {
if pool.size >= 0xff0 || immaddr(int32((p.Pc+int64(sz)+4)+4+int64(12+pool.size)-int64(pool.start+8))) == 0 { if pool.size >= 0xff0 || immaddr(int32((p.Pc+int64(sz)+4)+4+int64(12+pool.size)-int64(pool.start+8))) == 0 {
return flushpool(ctxt, p, 1, 0) return flushpool(ctxt, newprog, p, 1, 0)
} else if p.Link == nil { } else if p.Link == nil {
return flushpool(ctxt, p, 2, 0) return flushpool(ctxt, newprog, p, 2, 0)
} }
return false return false
} }
func flushpool(ctxt *obj.Link, p *obj.Prog, skip int, force int) bool { func flushpool(ctxt *obj.Link, newprog obj.ProgAlloc, p *obj.Prog, skip int, force int) bool {
if ctxt.Blitrl != nil { if ctxt.Blitrl != nil {
if skip != 0 { if skip != 0 {
if false && skip == 1 { if false && skip == 1 {
fmt.Printf("note: flush literal pool at %x: len=%d ref=%x\n", uint64(p.Pc+4), pool.size, pool.start) fmt.Printf("note: flush literal pool at %x: len=%d ref=%x\n", uint64(p.Pc+4), pool.size, pool.start)
} }
q := ctxt.NewProg() q := newprog()
q.As = AB q.As = AB
q.To.Type = obj.TYPE_BRANCH q.To.Type = obj.TYPE_BRANCH
q.Pcond = p.Link q.Pcond = p.Link
...@@ -822,7 +822,7 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int, force int) bool { ...@@ -822,7 +822,7 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int, force int) bool {
} }
if ctxt.Headtype == obj.Hnacl && pool.size%16 != 0 { if ctxt.Headtype == obj.Hnacl && pool.size%16 != 0 {
// if pool is not multiple of 16 bytes, add an alignment marker // if pool is not multiple of 16 bytes, add an alignment marker
q := ctxt.NewProg() q := newprog()
q.As = ADATABUNDLEEND q.As = ADATABUNDLEEND
ctxt.Elitrl.Link = q ctxt.Elitrl.Link = q
...@@ -850,7 +850,7 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int, force int) bool { ...@@ -850,7 +850,7 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int, force int) bool {
return false return false
} }
func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { func addpool(ctxt *obj.Link, newprog obj.ProgAlloc, p *obj.Prog, a *obj.Addr) {
var t obj.Prog var t obj.Prog
c := aclass(ctxt, a) c := aclass(ctxt, a)
...@@ -894,7 +894,7 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { ...@@ -894,7 +894,7 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
if ctxt.Headtype == obj.Hnacl && pool.size%16 == 0 { if ctxt.Headtype == obj.Hnacl && pool.size%16 == 0 {
// start a new data bundle // start a new data bundle
q := ctxt.NewProg() q := newprog()
q.As = ADATABUNDLE q.As = ADATABUNDLE
q.Pc = int64(pool.size) q.Pc = int64(pool.size)
pool.size += 4 pool.size += 4
...@@ -908,7 +908,7 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { ...@@ -908,7 +908,7 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
ctxt.Elitrl = q ctxt.Elitrl = q
} }
q := ctxt.NewProg() q := newprog()
*q = t *q = t
q.Pc = int64(pool.size) q.Pc = int64(pool.size)
......
...@@ -39,7 +39,7 @@ import ( ...@@ -39,7 +39,7 @@ import (
var progedit_tlsfallback *obj.LSym var progedit_tlsfallback *obj.LSym
func progedit(ctxt *obj.Link, p *obj.Prog) { func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
p.From.Class = 0 p.From.Class = 0
p.To.Class = 0 p.To.Class = 0
...@@ -80,7 +80,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { ...@@ -80,7 +80,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
p.To.Reg = REGTMP p.To.Reg = REGTMP
// BL runtime.read_tls_fallback(SB) // BL runtime.read_tls_fallback(SB)
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ABL p.As = ABL
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
...@@ -88,7 +88,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { ...@@ -88,7 +88,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
p.To.Offset = 0 p.To.Offset = 0
// MOVW R11, LR // MOVW R11, LR
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVW p.As = AMOVW
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -130,12 +130,12 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { ...@@ -130,12 +130,12 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
} }
if ctxt.Flag_dynlink { if ctxt.Flag_dynlink {
rewriteToUseGot(ctxt, p) rewriteToUseGot(ctxt, p, newprog)
} }
} }
// Rewrite p, if necessary, to access global data via the global offset table. // Rewrite p, if necessary, to access global data via the global offset table.
func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO { if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO {
// ADUFFxxx $offset // ADUFFxxx $offset
// becomes // becomes
...@@ -158,13 +158,13 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -158,13 +158,13 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
p.To.Name = obj.NAME_NONE p.To.Name = obj.NAME_NONE
p.To.Offset = 0 p.To.Offset = 0
p.To.Sym = nil p.To.Sym = nil
p1 := obj.Appendp(ctxt, p) p1 := obj.Appendp(p, newprog)
p1.As = AADD p1.As = AADD
p1.From.Type = obj.TYPE_CONST p1.From.Type = obj.TYPE_CONST
p1.From.Offset = offset p1.From.Offset = offset
p1.To.Type = obj.TYPE_REG p1.To.Type = obj.TYPE_REG
p1.To.Reg = REG_R9 p1.To.Reg = REG_R9
p2 := obj.Appendp(ctxt, p1) p2 := obj.Appendp(p1, newprog)
p2.As = obj.ACALL p2.As = obj.ACALL
p2.To.Type = obj.TYPE_MEM p2.To.Type = obj.TYPE_MEM
p2.To.Reg = REG_R9 p2.To.Reg = REG_R9
...@@ -186,7 +186,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -186,7 +186,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_GOTREF p.From.Name = obj.NAME_GOTREF
if p.From.Offset != 0 { if p.From.Offset != 0 {
q := obj.Appendp(ctxt, p) q := obj.Appendp(p, newprog)
q.As = AADD q.As = AADD
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = p.From.Offset q.From.Offset = p.From.Offset
...@@ -220,8 +220,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -220,8 +220,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
if source.Type != obj.TYPE_MEM { if source.Type != obj.TYPE_MEM {
ctxt.Diag("don't know how to handle %v with -dynlink", p) ctxt.Diag("don't know how to handle %v with -dynlink", p)
} }
p1 := obj.Appendp(ctxt, p) p1 := obj.Appendp(p, newprog)
p2 := obj.Appendp(ctxt, p1) p2 := obj.Appendp(p1, newprog)
p1.As = AMOVW p1.As = AMOVW
p1.From.Type = obj.TYPE_MEM p1.From.Type = obj.TYPE_MEM
...@@ -254,7 +254,7 @@ const ( ...@@ -254,7 +254,7 @@ const (
LEAF = 1 << 2 LEAF = 1 << 2
) )
func preprocess(ctxt *obj.Link, cursym *obj.LSym) { func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
autosize := int32(0) autosize := int32(0)
ctxt.Cursym = cursym ctxt.Cursym = cursym
...@@ -263,7 +263,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -263,7 +263,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
return return
} }
softfloat(ctxt, cursym) softfloat(ctxt, newprog, cursym)
p := cursym.Text p := cursym.Text
autoffset := int32(p.To.Offset) autoffset := int32(p.To.Offset)
...@@ -370,11 +370,11 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -370,11 +370,11 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
if p.From3.Offset&obj.NOSPLIT == 0 { if p.From3.Offset&obj.NOSPLIT == 0 {
p = stacksplit(ctxt, p, autosize) // emit split check p = stacksplit(ctxt, p, newprog, autosize) // emit split check
} }
// MOVW.W R14,$-autosize(SP) // MOVW.W R14,$-autosize(SP)
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVW p.As = AMOVW
p.Scond |= C_WBIT p.Scond |= C_WBIT
...@@ -406,7 +406,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -406,7 +406,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// The NOP is needed to give the jumps somewhere to land. // 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. // It is a liblink NOP, not an ARM NOP: it encodes to 0 instruction bytes.
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVW p.As = AMOVW
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG p.From.Reg = REGG
...@@ -414,19 +414,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -414,19 +414,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R1 p.To.Reg = REG_R1
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ACMP p.As = ACMP
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = 0 p.From.Offset = 0
p.Reg = REG_R1 p.Reg = REG_R1
// B.NE checkargp // B.NE checkargp
bne := obj.Appendp(ctxt, p) bne := obj.Appendp(p, newprog)
bne.As = ABNE bne.As = ABNE
bne.To.Type = obj.TYPE_BRANCH bne.To.Type = obj.TYPE_BRANCH
// end: NOP // end: NOP
end := obj.Appendp(ctxt, bne) end := obj.Appendp(bne, newprog)
end.As = obj.ANOP end.As = obj.ANOP
// find end of function // find end of function
...@@ -435,7 +435,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -435,7 +435,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
// MOVW panic_argp(R1), R2 // MOVW panic_argp(R1), R2
mov := obj.Appendp(ctxt, last) mov := obj.Appendp(last, newprog)
mov.As = AMOVW mov.As = AMOVW
mov.From.Type = obj.TYPE_MEM mov.From.Type = obj.TYPE_MEM
mov.From.Reg = REG_R1 mov.From.Reg = REG_R1
...@@ -447,7 +447,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -447,7 +447,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
bne.Pcond = mov bne.Pcond = mov
// ADD $(autosize+4), R13, R3 // ADD $(autosize+4), R13, R3
p = obj.Appendp(ctxt, mov) p = obj.Appendp(mov, newprog)
p.As = AADD p.As = AADD
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(autosize) + 4 p.From.Offset = int64(autosize) + 4
...@@ -456,20 +456,20 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -456,20 +456,20 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Reg = REG_R3 p.To.Reg = REG_R3
// CMP R2, R3 // CMP R2, R3
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ACMP p.As = ACMP
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R2 p.From.Reg = REG_R2
p.Reg = REG_R3 p.Reg = REG_R3
// B.NE end // B.NE end
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ABNE p.As = ABNE
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
p.Pcond = end p.Pcond = end
// ADD $4, R13, R4 // ADD $4, R13, R4
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AADD p.As = AADD
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = 4 p.From.Offset = 4
...@@ -478,7 +478,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -478,7 +478,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Reg = REG_R4 p.To.Reg = REG_R4
// MOVW R4, panic_argp(R1) // MOVW R4, panic_argp(R1)
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVW p.As = AMOVW
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R4 p.From.Reg = REG_R4
...@@ -487,7 +487,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -487,7 +487,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Offset = 0 // Panic.argp p.To.Offset = 0 // Panic.argp
// B end // B end
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AB p.As = AB
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
p.Pcond = end p.Pcond = end
...@@ -527,7 +527,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -527,7 +527,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// with the same stackframe, so no spadj. // with the same stackframe, so no spadj.
if p.To.Sym != nil { // retjmp if p.To.Sym != nil { // retjmp
p.To.Reg = REGLINK p.To.Reg = REGLINK
q2 = obj.Appendp(ctxt, p) q2 = obj.Appendp(p, newprog)
q2.As = AB q2.As = AB
q2.To.Type = obj.TYPE_BRANCH q2.To.Type = obj.TYPE_BRANCH
q2.To.Sym = p.To.Sym q2.To.Sym = p.To.Sym
...@@ -576,7 +576,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -576,7 +576,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Reg = REGTMP p.To.Reg = REGTMP
/* MOV a,m_divmod(REGTMP) */ /* MOV a,m_divmod(REGTMP) */
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVW p.As = AMOVW
p.Pos = q1.Pos p.Pos = q1.Pos
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -586,7 +586,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -586,7 +586,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Offset = 8 * 4 // offset of m.divmod p.To.Offset = 8 * 4 // offset of m.divmod
/* MOV b, R8 */ /* MOV b, R8 */
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVW p.As = AMOVW
p.Pos = q1.Pos p.Pos = q1.Pos
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -599,7 +599,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -599,7 +599,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Offset = 0 p.To.Offset = 0
/* CALL appropriate */ /* CALL appropriate */
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ABL p.As = ABL
p.Pos = q1.Pos p.Pos = q1.Pos
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
...@@ -618,7 +618,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -618,7 +618,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
/* MOV REGTMP, b */ /* MOV REGTMP, b */
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVW p.As = AMOVW
p.Pos = q1.Pos p.Pos = q1.Pos
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -645,7 +645,7 @@ func isfloatreg(a *obj.Addr) bool { ...@@ -645,7 +645,7 @@ func isfloatreg(a *obj.Addr) bool {
return a.Type == obj.TYPE_REG && REG_F0 <= a.Reg && a.Reg <= REG_F15 return a.Type == obj.TYPE_REG && REG_F0 <= a.Reg && a.Reg <= REG_F15
} }
func softfloat(ctxt *obj.Link, cursym *obj.LSym) { func softfloat(ctxt *obj.Link, newprog obj.ProgAlloc, cursym *obj.LSym) {
if obj.GOARM > 5 { if obj.GOARM > 5 {
return return
} }
...@@ -699,7 +699,7 @@ func softfloat(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -699,7 +699,7 @@ func softfloat(ctxt *obj.Link, cursym *obj.LSym) {
soft: soft:
if wasfloat == 0 || (p.Mark&LABEL != 0) { if wasfloat == 0 || (p.Mark&LABEL != 0) {
next = ctxt.NewProg() next = newprog()
*next = *p *next = *p
// BL _sfloat(SB) // BL _sfloat(SB)
...@@ -722,9 +722,9 @@ func softfloat(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -722,9 +722,9 @@ func softfloat(ctxt *obj.Link, cursym *obj.LSym) {
} }
} }
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize int32) *obj.Prog {
// MOVW g_stackguard(g), R1 // MOVW g_stackguard(g), R1
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVW p.As = AMOVW
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
...@@ -739,7 +739,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -739,7 +739,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
if framesize <= obj.StackSmall { if framesize <= obj.StackSmall {
// small stack: SP < stackguard // small stack: SP < stackguard
// CMP stackguard, SP // CMP stackguard, SP
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ACMP p.As = ACMP
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -749,7 +749,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -749,7 +749,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// large stack: SP-framesize < stackguard-StackSmall // large stack: SP-framesize < stackguard-StackSmall
// MOVW $-(framesize-StackSmall)(SP), R2 // MOVW $-(framesize-StackSmall)(SP), R2
// CMP stackguard, R2 // CMP stackguard, R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVW p.As = AMOVW
p.From.Type = obj.TYPE_ADDR p.From.Type = obj.TYPE_ADDR
...@@ -758,7 +758,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -758,7 +758,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2 p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ACMP p.As = ACMP
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1 p.From.Reg = REG_R1
...@@ -774,14 +774,14 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -774,14 +774,14 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// SUB.NE R1, R2 // SUB.NE R1, R2
// MOVW.NE $(framesize+(StackGuard-StackSmall)), R3 // MOVW.NE $(framesize+(StackGuard-StackSmall)), R3
// CMP.NE R3, R2 // CMP.NE R3, R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ACMP p.As = ACMP
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1))) p.From.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1)))
p.Reg = REG_R1 p.Reg = REG_R1
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVW p.As = AMOVW
p.From.Type = obj.TYPE_ADDR p.From.Type = obj.TYPE_ADDR
p.From.Reg = REGSP p.From.Reg = REGSP
...@@ -790,7 +790,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -790,7 +790,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Reg = REG_R2 p.To.Reg = REG_R2
p.Scond = C_SCOND_NE p.Scond = C_SCOND_NE
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ASUB p.As = ASUB
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1 p.From.Reg = REG_R1
...@@ -798,7 +798,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -798,7 +798,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Reg = REG_R2 p.To.Reg = REG_R2
p.Scond = C_SCOND_NE p.Scond = C_SCOND_NE
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVW p.As = AMOVW
p.From.Type = obj.TYPE_ADDR p.From.Type = obj.TYPE_ADDR
p.From.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall) p.From.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall)
...@@ -806,7 +806,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -806,7 +806,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Reg = REG_R3 p.To.Reg = REG_R3
p.Scond = C_SCOND_NE p.Scond = C_SCOND_NE
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ACMP p.As = ACMP
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3 p.From.Reg = REG_R3
...@@ -815,7 +815,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -815,7 +815,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
} }
// BLS call-to-morestack // BLS call-to-morestack
bls := obj.Appendp(ctxt, p) bls := obj.Appendp(p, newprog)
bls.As = ABLS bls.As = ABLS
bls.To.Type = obj.TYPE_BRANCH bls.To.Type = obj.TYPE_BRANCH
...@@ -826,11 +826,11 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -826,11 +826,11 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// Now we are at the end of the function, but logically // Now we are at the end of the function, but logically
// we are still in function prologue. We need to fix the // we are still in function prologue. We need to fix the
// SP data and PCDATA. // SP data and PCDATA.
spfix := obj.Appendp(ctxt, last) spfix := obj.Appendp(last, newprog)
spfix.As = obj.ANOP spfix.As = obj.ANOP
spfix.Spadj = -framesize spfix.Spadj = -framesize
pcdata := obj.Appendp(ctxt, spfix) pcdata := obj.Appendp(spfix, newprog)
pcdata.Pos = ctxt.Cursym.Text.Pos pcdata.Pos = ctxt.Cursym.Text.Pos
pcdata.As = obj.APCDATA pcdata.As = obj.APCDATA
pcdata.From.Type = obj.TYPE_CONST pcdata.From.Type = obj.TYPE_CONST
...@@ -839,7 +839,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -839,7 +839,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
pcdata.To.Offset = -1 // pcdata starts at -1 at function entry pcdata.To.Offset = -1 // pcdata starts at -1 at function entry
// MOVW LR, R3 // MOVW LR, R3
movw := obj.Appendp(ctxt, pcdata) movw := obj.Appendp(pcdata, newprog)
movw.As = AMOVW movw.As = AMOVW
movw.From.Type = obj.TYPE_REG movw.From.Type = obj.TYPE_REG
movw.From.Reg = REGLINK movw.From.Reg = REGLINK
...@@ -849,7 +849,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -849,7 +849,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
bls.Pcond = movw bls.Pcond = movw
// BL runtime.morestack // BL runtime.morestack
call := obj.Appendp(ctxt, movw) call := obj.Appendp(movw, newprog)
call.As = obj.ACALL call.As = obj.ACALL
call.To.Type = obj.TYPE_BRANCH call.To.Type = obj.TYPE_BRANCH
morestack := "runtime.morestack" morestack := "runtime.morestack"
...@@ -862,7 +862,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -862,7 +862,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
call.To.Sym = obj.Linklookup(ctxt, morestack, 0) call.To.Sym = obj.Linklookup(ctxt, morestack, 0)
// B start // B start
b := obj.Appendp(ctxt, call) b := obj.Appendp(call, newprog)
b.As = obj.AJMP b.As = obj.AJMP
b.To.Type = obj.TYPE_BRANCH b.To.Type = obj.TYPE_BRANCH
b.Pcond = ctxt.Cursym.Text.Link b.Pcond = ctxt.Cursym.Text.Link
......
...@@ -524,7 +524,7 @@ var pool struct { ...@@ -524,7 +524,7 @@ var pool struct {
size uint32 size uint32
} }
func span7(ctxt *obj.Link, cursym *obj.LSym) { func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p := cursym.Text p := cursym.Text
if p == nil || p.Link == nil { // handle external functions and ELF section symbols if p == nil || p.Link == nil { // handle external functions and ELF section symbols
return return
...@@ -557,19 +557,19 @@ func span7(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -557,19 +557,19 @@ func span7(ctxt *obj.Link, cursym *obj.LSym) {
switch o.flag & (LFROM | LTO) { switch o.flag & (LFROM | LTO) {
case LFROM: case LFROM:
addpool(ctxt, p, &p.From) addpool(ctxt, newprog, p, &p.From)
case LTO: case LTO:
addpool(ctxt, p, &p.To) addpool(ctxt, newprog, p, &p.To)
break break
} }
if p.As == AB || p.As == obj.ARET || p.As == AERET { /* TODO: other unconditional operations */ if p.As == AB || p.As == obj.ARET || p.As == AERET { /* TODO: other unconditional operations */
checkpool(ctxt, p, 0) checkpool(ctxt, newprog, p, 0)
} }
c += int64(m) c += int64(m)
if ctxt.Blitrl != nil { if ctxt.Blitrl != nil {
checkpool(ctxt, p, 1) checkpool(ctxt, newprog, p, 1)
} }
} }
...@@ -598,14 +598,14 @@ func span7(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -598,14 +598,14 @@ func span7(ctxt *obj.Link, cursym *obj.LSym) {
if (o.type_ == 7 || o.type_ == 39) && p.Pcond != nil { // 7: BEQ and like, 39: CBZ and like if (o.type_ == 7 || o.type_ == 39) && p.Pcond != nil { // 7: BEQ and like, 39: CBZ and like
otxt := p.Pcond.Pc - c otxt := p.Pcond.Pc - c
if otxt <= -(1<<18)+10 || otxt >= (1<<18)-10 { if otxt <= -(1<<18)+10 || otxt >= (1<<18)-10 {
q := ctxt.NewProg() q := newprog()
q.Link = p.Link q.Link = p.Link
p.Link = q p.Link = q
q.As = AB q.As = AB
q.To.Type = obj.TYPE_BRANCH q.To.Type = obj.TYPE_BRANCH
q.Pcond = p.Pcond q.Pcond = p.Pcond
p.Pcond = q p.Pcond = q
q = ctxt.NewProg() q = newprog()
q.Link = p.Link q.Link = p.Link
p.Link = q p.Link = q
q.As = AB q.As = AB
...@@ -670,21 +670,21 @@ func span7(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -670,21 +670,21 @@ func span7(ctxt *obj.Link, cursym *obj.LSym) {
* to go out of range of a 1Mb PC-relative offset * to go out of range of a 1Mb PC-relative offset
* drop the pool now, and branch round it. * drop the pool now, and branch round it.
*/ */
func checkpool(ctxt *obj.Link, p *obj.Prog, skip int) { func checkpool(ctxt *obj.Link, newprog obj.ProgAlloc, p *obj.Prog, skip int) {
if pool.size >= 0xffff0 || !ispcdisp(int32(p.Pc+4+int64(pool.size)-int64(pool.start)+8)) { if pool.size >= 0xffff0 || !ispcdisp(int32(p.Pc+4+int64(pool.size)-int64(pool.start)+8)) {
flushpool(ctxt, p, skip) flushpool(ctxt, newprog, p, skip)
} else if p.Link == nil { } else if p.Link == nil {
flushpool(ctxt, p, 2) flushpool(ctxt, newprog, p, 2)
} }
} }
func flushpool(ctxt *obj.Link, p *obj.Prog, skip int) { func flushpool(ctxt *obj.Link, newprog obj.ProgAlloc, p *obj.Prog, skip int) {
if ctxt.Blitrl != nil { if ctxt.Blitrl != nil {
if skip != 0 { if skip != 0 {
if ctxt.Debugvlog && skip == 1 { if ctxt.Debugvlog && skip == 1 {
fmt.Printf("note: flush literal pool at %#x: len=%d ref=%x\n", uint64(p.Pc+4), pool.size, pool.start) fmt.Printf("note: flush literal pool at %#x: len=%d ref=%x\n", uint64(p.Pc+4), pool.size, pool.start)
} }
q := ctxt.NewProg() q := newprog()
q.As = AB q.As = AB
q.To.Type = obj.TYPE_BRANCH q.To.Type = obj.TYPE_BRANCH
q.Pcond = p.Link q.Pcond = p.Link
...@@ -715,10 +715,10 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int) { ...@@ -715,10 +715,10 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int) {
/* /*
* TODO: hash * TODO: hash
*/ */
func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { func addpool(ctxt *obj.Link, newprog obj.ProgAlloc, p *obj.Prog, a *obj.Addr) {
c := aclass(ctxt, a) c := aclass(ctxt, a)
lit := ctxt.Instoffset lit := ctxt.Instoffset
t := *ctxt.NewProg() t := *newprog()
t.As = AWORD t.As = AWORD
sz := 4 sz := 4
...@@ -789,7 +789,7 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { ...@@ -789,7 +789,7 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
} }
} }
q := ctxt.NewProg() q := newprog()
*q = t *q = t
q.Pc = int64(pool.size) q.Pc = int64(pool.size)
if ctxt.Blitrl == nil { if ctxt.Blitrl == nil {
......
...@@ -48,9 +48,9 @@ var complements = []obj.As{ ...@@ -48,9 +48,9 @@ var complements = []obj.As{
ACMNW: ACMPW, ACMNW: ACMPW,
} }
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize int32) *obj.Prog {
// MOV g_stackguard(g), R1 // MOV g_stackguard(g), R1
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVD p.As = AMOVD
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
...@@ -67,7 +67,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -67,7 +67,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// small stack: SP < stackguard // small stack: SP < stackguard
// MOV SP, R2 // MOV SP, R2
// CMP stackguard, R2 // CMP stackguard, R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVD p.As = AMOVD
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -75,7 +75,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -75,7 +75,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2 p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ACMP p.As = ACMP
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1 p.From.Reg = REG_R1
...@@ -84,7 +84,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -84,7 +84,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// large stack: SP-framesize < stackguard-StackSmall // large stack: SP-framesize < stackguard-StackSmall
// SUB $(framesize-StackSmall), SP, R2 // SUB $(framesize-StackSmall), SP, R2
// CMP stackguard, R2 // CMP stackguard, R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ASUB p.As = ASUB
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
...@@ -93,7 +93,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -93,7 +93,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2 p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ACMP p.As = ACMP
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1 p.From.Reg = REG_R1
...@@ -110,19 +110,19 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -110,19 +110,19 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// SUB R1, R2 // SUB R1, R2
// MOV $(framesize+(StackGuard-StackSmall)), R3 // MOV $(framesize+(StackGuard-StackSmall)), R3
// CMP R3, R2 // CMP R3, R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ACMP p.As = ACMP
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = obj.StackPreempt p.From.Offset = obj.StackPreempt
p.Reg = REG_R1 p.Reg = REG_R1
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
q = p q = p
p.As = ABEQ p.As = ABEQ
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AADD p.As = AADD
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = obj.StackGuard p.From.Offset = obj.StackGuard
...@@ -130,21 +130,21 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -130,21 +130,21 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2 p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ASUB p.As = ASUB
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1 p.From.Reg = REG_R1
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2 p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVD p.As = AMOVD
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall) p.From.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall)
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R3 p.To.Reg = REG_R3
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ACMP p.As = ACMP
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3 p.From.Reg = REG_R3
...@@ -152,7 +152,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -152,7 +152,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
} }
// BLS do-morestack // BLS do-morestack
bls := obj.Appendp(ctxt, p) bls := obj.Appendp(p, newprog)
bls.As = ABLS bls.As = ABLS
bls.To.Type = obj.TYPE_BRANCH bls.To.Type = obj.TYPE_BRANCH
...@@ -163,11 +163,11 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -163,11 +163,11 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// Now we are at the end of the function, but logically // Now we are at the end of the function, but logically
// we are still in function prologue. We need to fix the // we are still in function prologue. We need to fix the
// SP data and PCDATA. // SP data and PCDATA.
spfix := obj.Appendp(ctxt, last) spfix := obj.Appendp(last, newprog)
spfix.As = obj.ANOP spfix.As = obj.ANOP
spfix.Spadj = -framesize spfix.Spadj = -framesize
pcdata := obj.Appendp(ctxt, spfix) pcdata := obj.Appendp(spfix, newprog)
pcdata.Pos = ctxt.Cursym.Text.Pos pcdata.Pos = ctxt.Cursym.Text.Pos
pcdata.As = obj.APCDATA pcdata.As = obj.APCDATA
pcdata.From.Type = obj.TYPE_CONST pcdata.From.Type = obj.TYPE_CONST
...@@ -176,7 +176,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -176,7 +176,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
pcdata.To.Offset = -1 // pcdata starts at -1 at function entry pcdata.To.Offset = -1 // pcdata starts at -1 at function entry
// MOV LR, R3 // MOV LR, R3
movlr := obj.Appendp(ctxt, pcdata) movlr := obj.Appendp(pcdata, newprog)
movlr.As = AMOVD movlr.As = AMOVD
movlr.From.Type = obj.TYPE_REG movlr.From.Type = obj.TYPE_REG
movlr.From.Reg = REGLINK movlr.From.Reg = REGLINK
...@@ -189,7 +189,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -189,7 +189,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
debug := movlr debug := movlr
if false { if false {
debug = obj.Appendp(ctxt, debug) debug = obj.Appendp(debug, newprog)
debug.As = AMOVD debug.As = AMOVD
debug.From.Type = obj.TYPE_CONST debug.From.Type = obj.TYPE_CONST
debug.From.Offset = int64(framesize) debug.From.Offset = int64(framesize)
...@@ -198,7 +198,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -198,7 +198,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
} }
// BL runtime.morestack(SB) // BL runtime.morestack(SB)
call := obj.Appendp(ctxt, debug) call := obj.Appendp(debug, newprog)
call.As = ABL call.As = ABL
call.To.Type = obj.TYPE_BRANCH call.To.Type = obj.TYPE_BRANCH
morestack := "runtime.morestack" morestack := "runtime.morestack"
...@@ -211,7 +211,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -211,7 +211,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
call.To.Sym = obj.Linklookup(ctxt, morestack, 0) call.To.Sym = obj.Linklookup(ctxt, morestack, 0)
// B start // B start
jmp := obj.Appendp(ctxt, call) jmp := obj.Appendp(call, newprog)
jmp.As = AB jmp.As = AB
jmp.To.Type = obj.TYPE_BRANCH jmp.To.Type = obj.TYPE_BRANCH
jmp.Pcond = ctxt.Cursym.Text.Link jmp.Pcond = ctxt.Cursym.Text.Link
...@@ -224,7 +224,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -224,7 +224,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
return bls return bls
} }
func progedit(ctxt *obj.Link, p *obj.Prog) { func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
p.From.Class = 0 p.From.Class = 0
p.To.Class = 0 p.To.Class = 0
...@@ -326,12 +326,12 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { ...@@ -326,12 +326,12 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
} }
if ctxt.Flag_dynlink { if ctxt.Flag_dynlink {
rewriteToUseGot(ctxt, p) rewriteToUseGot(ctxt, p, newprog)
} }
} }
// Rewrite p, if necessary, to access global data via the global offset table. // Rewrite p, if necessary, to access global data via the global offset table.
func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO { if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO {
// ADUFFxxx $offset // ADUFFxxx $offset
// becomes // becomes
...@@ -354,13 +354,13 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -354,13 +354,13 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
p.To.Name = obj.NAME_NONE p.To.Name = obj.NAME_NONE
p.To.Offset = 0 p.To.Offset = 0
p.To.Sym = nil p.To.Sym = nil
p1 := obj.Appendp(ctxt, p) p1 := obj.Appendp(p, newprog)
p1.As = AADD p1.As = AADD
p1.From.Type = obj.TYPE_CONST p1.From.Type = obj.TYPE_CONST
p1.From.Offset = offset p1.From.Offset = offset
p1.To.Type = obj.TYPE_REG p1.To.Type = obj.TYPE_REG
p1.To.Reg = REGTMP p1.To.Reg = REGTMP
p2 := obj.Appendp(ctxt, p1) p2 := obj.Appendp(p1, newprog)
p2.As = obj.ACALL p2.As = obj.ACALL
p2.To.Type = obj.TYPE_REG p2.To.Type = obj.TYPE_REG
p2.To.Reg = REGTMP p2.To.Reg = REGTMP
...@@ -381,7 +381,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -381,7 +381,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_GOTREF p.From.Name = obj.NAME_GOTREF
if p.From.Offset != 0 { if p.From.Offset != 0 {
q := obj.Appendp(ctxt, p) q := obj.Appendp(p, newprog)
q.As = AADD q.As = AADD
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = p.From.Offset q.From.Offset = p.From.Offset
...@@ -415,8 +415,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -415,8 +415,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
if source.Type != obj.TYPE_MEM { if source.Type != obj.TYPE_MEM {
ctxt.Diag("don't know how to handle %v with -dynlink", p) ctxt.Diag("don't know how to handle %v with -dynlink", p)
} }
p1 := obj.Appendp(ctxt, p) p1 := obj.Appendp(p, newprog)
p2 := obj.Appendp(ctxt, p1) p2 := obj.Appendp(p1, newprog)
p1.As = AMOVD p1.As = AMOVD
p1.From.Type = obj.TYPE_MEM p1.From.Type = obj.TYPE_MEM
p1.From.Sym = source.Sym p1.From.Sym = source.Sym
...@@ -441,7 +441,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -441,7 +441,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
obj.Nopout(p) obj.Nopout(p)
} }
func preprocess(ctxt *obj.Link, cursym *obj.LSym) { func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
ctxt.Cursym = cursym ctxt.Cursym = cursym
if cursym.Text == nil || cursym.Text.Link == nil { if cursym.Text == nil || cursym.Text.Link == nil {
...@@ -561,7 +561,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -561,7 +561,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
if !(p.From3.Offset&obj.NOSPLIT != 0) { if !(p.From3.Offset&obj.NOSPLIT != 0) {
p = stacksplit(ctxt, p, ctxt.Autosize) // emit split check p = stacksplit(ctxt, p, newprog, ctxt.Autosize) // emit split check
} }
aoffset = ctxt.Autosize aoffset = ctxt.Autosize
...@@ -583,7 +583,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -583,7 +583,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// Store link register before decrementing SP, so if a signal comes // Store link register before decrementing SP, so if a signal comes
// during the execution of the function prologue, the traceback // during the execution of the function prologue, the traceback
// code will not see a half-updated stack frame. // code will not see a half-updated stack frame.
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.Pos = p.Pos q.Pos = p.Pos
q.As = ASUB q.As = ASUB
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
...@@ -592,7 +592,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -592,7 +592,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REGTMP q.To.Reg = REGTMP
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.Pos = p.Pos q.Pos = p.Pos
q.As = AMOVD q.As = AMOVD
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
...@@ -600,7 +600,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -600,7 +600,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_MEM q.To.Type = obj.TYPE_MEM
q.To.Reg = REGTMP q.To.Reg = REGTMP
q1 = obj.Appendp(ctxt, q) q1 = obj.Appendp(q, newprog)
q1.Pos = p.Pos q1.Pos = p.Pos
q1.As = AMOVD q1.As = AMOVD
q1.From.Type = obj.TYPE_REG q1.From.Type = obj.TYPE_REG
...@@ -610,7 +610,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -610,7 +610,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q1.Spadj = ctxt.Autosize q1.Spadj = ctxt.Autosize
} else { } else {
// small frame, update SP and save LR in a single MOVD.W instruction // small frame, update SP and save LR in a single MOVD.W instruction
q1 = obj.Appendp(ctxt, q) q1 = obj.Appendp(q, newprog)
q1.As = AMOVD q1.As = AMOVD
q1.Pos = p.Pos q1.Pos = p.Pos
q1.From.Type = obj.TYPE_REG q1.From.Type = obj.TYPE_REG
...@@ -641,7 +641,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -641,7 +641,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// It is a liblink NOP, not a ARM64 NOP: it encodes to 0 instruction bytes. // It is a liblink NOP, not a ARM64 NOP: it encodes to 0 instruction bytes.
q = q1 q = q1
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AMOVD q.As = AMOVD
q.From.Type = obj.TYPE_MEM q.From.Type = obj.TYPE_MEM
q.From.Reg = REGG q.From.Reg = REGG
...@@ -649,18 +649,18 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -649,18 +649,18 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R1 q.To.Reg = REG_R1
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = ACMP q.As = ACMP
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REGZERO q.From.Reg = REGZERO
q.Reg = REG_R1 q.Reg = REG_R1
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = ABEQ q.As = ABEQ
q.To.Type = obj.TYPE_BRANCH q.To.Type = obj.TYPE_BRANCH
q1 = q q1 = q
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AMOVD q.As = AMOVD
q.From.Type = obj.TYPE_MEM q.From.Type = obj.TYPE_MEM
q.From.Reg = REG_R1 q.From.Reg = REG_R1
...@@ -668,7 +668,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -668,7 +668,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R2 q.To.Reg = REG_R2
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AADD q.As = AADD
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(ctxt.Autosize) + 8 q.From.Offset = int64(ctxt.Autosize) + 8
...@@ -676,18 +676,18 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -676,18 +676,18 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R3 q.To.Reg = REG_R3
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = ACMP q.As = ACMP
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R2 q.From.Reg = REG_R2
q.Reg = REG_R3 q.Reg = REG_R3
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = ABNE q.As = ABNE
q.To.Type = obj.TYPE_BRANCH q.To.Type = obj.TYPE_BRANCH
q2 = q q2 = q
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AADD q.As = AADD
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = 8 q.From.Offset = 8
...@@ -695,7 +695,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -695,7 +695,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R4 q.To.Reg = REG_R4
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AMOVD q.As = AMOVD
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R4 q.From.Reg = REG_R4
...@@ -703,7 +703,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -703,7 +703,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Reg = REG_R1 q.To.Reg = REG_R1
q.To.Offset = 0 // Panic.argp q.To.Offset = 0 // Panic.argp
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = obj.ANOP q.As = obj.ANOP
q1.Pcond = q q1.Pcond = q
...@@ -744,7 +744,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -744,7 +744,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Reg = REGLINK p.To.Reg = REGLINK
p.Spadj = -aoffset p.Spadj = -aoffset
if ctxt.Autosize > aoffset { if ctxt.Autosize > aoffset {
q = ctxt.NewProg() q = newprog()
q.As = AADD q.As = AADD
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(ctxt.Autosize) - int64(aoffset) q.From.Offset = int64(ctxt.Autosize) - int64(aoffset)
...@@ -759,7 +759,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -759,7 +759,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
if p.As != obj.ARET { if p.As != obj.ARET {
q = ctxt.NewProg() q = newprog()
q.Pos = p.Pos q.Pos = p.Pos
q.Link = p.Link q.Link = p.Link
p.Link = q p.Link = q
......
...@@ -76,8 +76,8 @@ func mkfwd(sym *LSym) { ...@@ -76,8 +76,8 @@ func mkfwd(sym *LSym) {
} }
} }
func Appendp(ctxt *Link, q *Prog) *Prog { func Appendp(q *Prog, newprog ProgAlloc) *Prog {
p := ctxt.NewProg() p := newprog()
p.Link = q.Link p.Link = q.Link
q.Link = p q.Link = p
p.Pos = q.Pos p.Pos = q.Pos
......
...@@ -224,7 +224,8 @@ const ( ...@@ -224,7 +224,8 @@ const (
// Each Prog is charged to a specific source line in the debug information, // Each Prog is charged to a specific source line in the debug information,
// specified by Pos.Line(). // specified by Pos.Line().
// Every Prog has a Ctxt field that defines its context. // Every Prog has a Ctxt field that defines its context.
// Progs should be allocated using ctxt.NewProg(), not new(Prog). // For performance reasons, Progs usually are usually bulk allocated, cached, and reused;
// those bulk allocators should always be used, rather than new(Prog).
// //
// The other fields not yet mentioned are for use by the back ends and should // The other fields not yet mentioned are for use by the back ends and should
// be left zeroed by creators of Prog lists. // be left zeroed by creators of Prog lists.
...@@ -789,9 +790,9 @@ type SymVer struct { ...@@ -789,9 +790,9 @@ type SymVer struct {
// LinkArch is the definition of a single architecture. // LinkArch is the definition of a single architecture.
type LinkArch struct { type LinkArch struct {
*sys.Arch *sys.Arch
Preprocess func(*Link, *LSym) Preprocess func(*Link, *LSym, ProgAlloc)
Assemble func(*Link, *LSym) Assemble func(*Link, *LSym, ProgAlloc)
Progedit func(*Link, *Prog) Progedit func(*Link, *Prog, ProgAlloc)
UnaryDst map[As]bool // Instruction takes one operand, a destination. UnaryDst map[As]bool // Instruction takes one operand, a destination.
} }
......
...@@ -373,7 +373,7 @@ var oprange [ALAST & obj.AMask][]Optab ...@@ -373,7 +373,7 @@ var oprange [ALAST & obj.AMask][]Optab
var xcmp [C_NCLASS][C_NCLASS]bool var xcmp [C_NCLASS][C_NCLASS]bool
func span0(ctxt *obj.Link, cursym *obj.LSym) { func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p := cursym.Text p := cursym.Text
if p == nil || p.Link == nil { // handle external functions and ELF section symbols if p == nil || p.Link == nil { // handle external functions and ELF section symbols
return return
...@@ -430,7 +430,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -430,7 +430,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym) {
if o.type_ == 6 && p.Pcond != nil { if o.type_ == 6 && p.Pcond != nil {
otxt = p.Pcond.Pc - c otxt = p.Pcond.Pc - c
if otxt < -(1<<17)+10 || otxt >= (1<<17)-10 { if otxt < -(1<<17)+10 || otxt >= (1<<17)-10 {
q = ctxt.NewProg() q = newprog()
q.Link = p.Link q.Link = p.Link
p.Link = q p.Link = q
q.As = AJMP q.As = AJMP
...@@ -438,7 +438,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -438,7 +438,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_BRANCH q.To.Type = obj.TYPE_BRANCH
q.Pcond = p.Pcond q.Pcond = p.Pcond
p.Pcond = q p.Pcond = q
q = ctxt.NewProg() q = newprog()
q.Link = p.Link q.Link = p.Link
p.Link = q p.Link = q
q.As = AJMP q.As = AJMP
...@@ -446,8 +446,8 @@ func span0(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -446,8 +446,8 @@ func span0(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_BRANCH q.To.Type = obj.TYPE_BRANCH
q.Pcond = q.Link.Link q.Pcond = q.Link.Link
addnop(ctxt, p.Link) addnop(ctxt, p.Link, newprog)
addnop(ctxt, p) addnop(ctxt, p, newprog)
bflag = 1 bflag = 1
} }
} }
......
...@@ -37,7 +37,7 @@ import ( ...@@ -37,7 +37,7 @@ import (
"math" "math"
) )
func progedit(ctxt *obj.Link, p *obj.Prog) { func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
p.From.Class = 0 p.From.Class = 0
p.To.Class = 0 p.To.Class = 0
...@@ -133,7 +133,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { ...@@ -133,7 +133,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
} }
} }
func preprocess(ctxt *obj.Link, cursym *obj.LSym) { func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
// TODO(minux): add morestack short-cuts with small fixed frame-size. // TODO(minux): add morestack short-cuts with small fixed frame-size.
ctxt.Cursym = cursym ctxt.Cursym = cursym
...@@ -298,7 +298,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -298,7 +298,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Offset = int64(autosize) - ctxt.FixedFrameSize() p.To.Offset = int64(autosize) - ctxt.FixedFrameSize()
if p.From3.Offset&obj.NOSPLIT == 0 { if p.From3.Offset&obj.NOSPLIT == 0 {
p = stacksplit(ctxt, p, autosize) // emit split check p = stacksplit(ctxt, p, newprog, autosize) // emit split check
} }
q = p q = p
...@@ -309,7 +309,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -309,7 +309,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// Store link register before decrement SP, so if a signal comes // Store link register before decrement SP, so if a signal comes
// during the execution of the function prologue, the traceback // during the execution of the function prologue, the traceback
// code will not see a half-updated stack frame. // code will not see a half-updated stack frame.
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = mov q.As = mov
q.Pos = p.Pos q.Pos = p.Pos
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
...@@ -318,7 +318,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -318,7 +318,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Offset = int64(-autosize) q.To.Offset = int64(-autosize)
q.To.Reg = REGSP q.To.Reg = REGSP
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = add q.As = add
q.Pos = p.Pos q.Pos = p.Pos
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
...@@ -357,7 +357,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -357,7 +357,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// The NOP is needed to give the jumps somewhere to land. // 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. // It is a liblink NOP, not an mips NOP: it encodes to 0 instruction bytes.
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = mov q.As = mov
q.From.Type = obj.TYPE_MEM q.From.Type = obj.TYPE_MEM
...@@ -366,7 +366,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -366,7 +366,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R1 q.To.Reg = REG_R1
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = ABEQ q.As = ABEQ
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R1 q.From.Reg = REG_R1
...@@ -374,7 +374,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -374,7 +374,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.Mark |= BRANCH q.Mark |= BRANCH
p1 = q p1 = q
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = mov q.As = mov
q.From.Type = obj.TYPE_MEM q.From.Type = obj.TYPE_MEM
q.From.Reg = REG_R1 q.From.Reg = REG_R1
...@@ -382,7 +382,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -382,7 +382,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R2 q.To.Reg = REG_R2
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = add q.As = add
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(autosize) + ctxt.FixedFrameSize() q.From.Offset = int64(autosize) + ctxt.FixedFrameSize()
...@@ -390,7 +390,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -390,7 +390,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R3 q.To.Reg = REG_R3
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = ABNE q.As = ABNE
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R2 q.From.Reg = REG_R2
...@@ -399,7 +399,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -399,7 +399,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.Mark |= BRANCH q.Mark |= BRANCH
p2 = q p2 = q
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = add q.As = add
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = ctxt.FixedFrameSize() q.From.Offset = ctxt.FixedFrameSize()
...@@ -407,7 +407,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -407,7 +407,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R2 q.To.Reg = REG_R2
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = mov q.As = mov
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R2 q.From.Reg = REG_R2
...@@ -415,7 +415,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -415,7 +415,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Reg = REG_R1 q.To.Reg = REG_R1
q.To.Offset = 0 // Panic.argp q.To.Offset = 0 // Panic.argp
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = obj.ANOP q.As = obj.ANOP
p1.Pcond = q p1.Pcond = q
...@@ -456,7 +456,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -456,7 +456,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Reg = REGSP p.To.Reg = REGSP
p.Spadj = -autosize p.Spadj = -autosize
q = ctxt.NewProg() q = newprog()
q.As = AJMP q.As = AJMP
q.Pos = p.Pos q.Pos = p.Pos
q.To.Type = obj.TYPE_MEM q.To.Type = obj.TYPE_MEM
...@@ -481,7 +481,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -481,7 +481,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
if autosize != 0 { if autosize != 0 {
q = ctxt.NewProg() q = newprog()
q.As = add q.As = add
q.Pos = p.Pos q.Pos = p.Pos
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
...@@ -494,7 +494,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -494,7 +494,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.Link = q p.Link = q
} }
q1 = ctxt.NewProg() q1 = newprog()
q1.As = AJMP q1.As = AJMP
q1.Pos = p.Pos q1.Pos = p.Pos
if retSym != nil { // retjmp if retSym != nil { // retjmp
...@@ -535,7 +535,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -535,7 +535,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
p.As = AMOVF p.As = AMOVF
q = ctxt.NewProg() q = newprog()
*q = *p *q = *p
q.Link = p.Link q.Link = p.Link
p.Link = q p.Link = q
...@@ -564,7 +564,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -564,7 +564,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// NOP after each branch instruction. // NOP after each branch instruction.
for p = cursym.Text; p != nil; p = p.Link { for p = cursym.Text; p != nil; p = p.Link {
if p.Mark&BRANCH != 0 { if p.Mark&BRANCH != 0 {
addnop(ctxt, p) addnop(ctxt, p, newprog)
} }
} }
return return
...@@ -579,7 +579,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -579,7 +579,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
o++ o++
if p.Mark&NOSCHED != 0 { if p.Mark&NOSCHED != 0 {
if q1 != p { if q1 != p {
sched(ctxt, q1, q) sched(ctxt, newprog, q1, q)
} }
for ; p != nil; p = p.Link { for ; p != nil; p = p.Link {
if p.Mark&NOSCHED == 0 { if p.Mark&NOSCHED == 0 {
...@@ -594,18 +594,18 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -594,18 +594,18 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
if p.Mark&(LABEL|SYNC) != 0 { if p.Mark&(LABEL|SYNC) != 0 {
if q1 != p { if q1 != p {
sched(ctxt, q1, q) sched(ctxt, newprog, q1, q)
} }
q1 = p q1 = p
o = 1 o = 1
} }
if p.Mark&(BRANCH|SYNC) != 0 { if p.Mark&(BRANCH|SYNC) != 0 {
sched(ctxt, q1, p) sched(ctxt, newprog, q1, p)
q1 = p1 q1 = p1
o = 0 o = 0
} }
if o >= NSCHED { if o >= NSCHED {
sched(ctxt, q1, p) sched(ctxt, newprog, q1, p)
q1 = p1 q1 = p1
o = 0 o = 0
} }
...@@ -613,7 +613,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -613,7 +613,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
} }
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize int32) *obj.Prog {
// Leaf function with no frame is effectively NOSPLIT. // Leaf function with no frame is effectively NOSPLIT.
if framesize == 0 { if framesize == 0 {
return p return p
...@@ -632,7 +632,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -632,7 +632,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
} }
// MOV g_stackguard(g), R1 // MOV g_stackguard(g), R1
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = mov p.As = mov
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
...@@ -648,7 +648,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -648,7 +648,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
if framesize <= obj.StackSmall { if framesize <= obj.StackSmall {
// small stack: SP < stackguard // small stack: SP < stackguard
// AGTU SP, stackguard, R1 // AGTU SP, stackguard, R1
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ASGTU p.As = ASGTU
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -660,7 +660,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -660,7 +660,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// large stack: SP-framesize < stackguard-StackSmall // large stack: SP-framesize < stackguard-StackSmall
// ADD $-(framesize-StackSmall), SP, R2 // ADD $-(framesize-StackSmall), SP, R2
// SGTU R2, stackguard, R1 // SGTU R2, stackguard, R1
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = add p.As = add
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
...@@ -669,7 +669,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -669,7 +669,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2 p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ASGTU p.As = ASGTU
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R2 p.From.Reg = REG_R2
...@@ -692,7 +692,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -692,7 +692,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// SUB R1, R2 // SUB R1, R2
// MOV $(framesize+(StackGuard-StackSmall)), R1 // MOV $(framesize+(StackGuard-StackSmall)), R1
// SGTU R2, R1, R1 // SGTU R2, R1, R1
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = mov p.As = mov
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
...@@ -700,7 +700,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -700,7 +700,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2 p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
q = p q = p
p.As = ABEQ p.As = ABEQ
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -709,7 +709,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -709,7 +709,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
p.Mark |= BRANCH p.Mark |= BRANCH
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = add p.As = add
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = obj.StackGuard p.From.Offset = obj.StackGuard
...@@ -717,21 +717,21 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -717,21 +717,21 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2 p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = sub p.As = sub
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1 p.From.Reg = REG_R1
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2 p.To.Reg = REG_R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = mov p.As = mov
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R1 p.To.Reg = REG_R1
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ASGTU p.As = ASGTU
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R2 p.From.Reg = REG_R2
...@@ -741,7 +741,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -741,7 +741,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
} }
// q1: BNE R1, done // q1: BNE R1, done
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
q1 := p q1 := p
p.As = ABNE p.As = ABNE
...@@ -751,7 +751,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -751,7 +751,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.Mark |= BRANCH p.Mark |= BRANCH
// MOV LINK, R3 // MOV LINK, R3
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = mov p.As = mov
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -764,7 +764,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -764,7 +764,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
} }
// JAL runtime.morestack(SB) // JAL runtime.morestack(SB)
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AJAL p.As = AJAL
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
...@@ -778,7 +778,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -778,7 +778,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.Mark |= BRANCH p.Mark |= BRANCH
// JMP start // JMP start
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AJMP p.As = AJMP
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
...@@ -786,7 +786,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -786,7 +786,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.Mark |= BRANCH p.Mark |= BRANCH
// placeholder for q1's jump target // placeholder for q1's jump target
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = obj.ANOP // zero-width place holder p.As = obj.ANOP // zero-width place holder
q1.Pcond = p q1.Pcond = p
...@@ -794,8 +794,8 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -794,8 +794,8 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
return p return p
} }
func addnop(ctxt *obj.Link, p *obj.Prog) { func addnop(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
q := ctxt.NewProg() q := newprog()
// we want to use the canonical NOP (SLL $0,R0,R0) here, // we want to use the canonical NOP (SLL $0,R0,R0) here,
// however, as the assembler will always replace $0 // however, as the assembler will always replace $0
// as R0, we have to resort to manually encode the SLL // as R0, we have to resort to manually encode the SLL
...@@ -838,7 +838,7 @@ type Sch struct { ...@@ -838,7 +838,7 @@ type Sch struct {
comp bool comp bool
} }
func sched(ctxt *obj.Link, p0, pe *obj.Prog) { func sched(ctxt *obj.Link, newprog obj.ProgAlloc, p0, pe *obj.Prog) {
var sch [NSCHED]Sch var sch [NSCHED]Sch
/* /*
...@@ -923,7 +923,7 @@ func sched(ctxt *obj.Link, p0, pe *obj.Prog) { ...@@ -923,7 +923,7 @@ func sched(ctxt *obj.Link, p0, pe *obj.Prog) {
} }
for s[0].nop != 0 { for s[0].nop != 0 {
s[0].nop-- s[0].nop--
addnop(ctxt, p) addnop(ctxt, p, newprog)
} }
} }
} }
......
...@@ -117,7 +117,7 @@ func checkaddr(ctxt *Link, p *Prog, a *Addr) { ...@@ -117,7 +117,7 @@ func checkaddr(ctxt *Link, p *Prog, a *Addr) {
ctxt.Diag("invalid encoding for argument %v", p) ctxt.Diag("invalid encoding for argument %v", p)
} }
func linkpatch(ctxt *Link, sym *LSym) { func linkpatch(ctxt *Link, sym *LSym, newprog ProgAlloc) {
var c int32 var c int32
var name string var name string
var q *Prog var q *Prog
...@@ -130,7 +130,7 @@ func linkpatch(ctxt *Link, sym *LSym) { ...@@ -130,7 +130,7 @@ func linkpatch(ctxt *Link, sym *LSym) {
checkaddr(ctxt, p, &p.To) checkaddr(ctxt, p, &p.To)
if ctxt.Arch.Progedit != nil { if ctxt.Arch.Progedit != nil {
ctxt.Arch.Progedit(ctxt, p) ctxt.Arch.Progedit(ctxt, p, newprog)
} }
if p.To.Type != TYPE_BRANCH { if p.To.Type != TYPE_BRANCH {
continue continue
......
...@@ -15,6 +15,10 @@ type Plist struct { ...@@ -15,6 +15,10 @@ type Plist struct {
Curfn interface{} // holds a *gc.Node, if non-nil Curfn interface{} // holds a *gc.Node, if non-nil
} }
// ProgAlloc is a function that allocates Progs.
// It is used to provide access to cached/bulk-allocated Progs to the assemblers.
type ProgAlloc func() *Prog
func Flushplist(ctxt *Link, plist *Plist) { func Flushplist(ctxt *Link, plist *Plist) {
flushplist(ctxt, plist, !ctxt.Debugasm) flushplist(ctxt, plist, !ctxt.Debugasm)
} }
...@@ -97,6 +101,8 @@ func flushplist(ctxt *Link, plist *Plist, freeProgs bool) { ...@@ -97,6 +101,8 @@ func flushplist(ctxt *Link, plist *Plist, freeProgs bool) {
etext = p etext = p
} }
newprog := ProgAlloc(ctxt.NewProg)
// Add reference to Go arguments for C or assembly functions without them. // Add reference to Go arguments for C or assembly functions without them.
for _, s := range text { for _, s := range text {
if !strings.HasPrefix(s.Name, "\"\".") { if !strings.HasPrefix(s.Name, "\"\".") {
...@@ -111,7 +117,7 @@ func flushplist(ctxt *Link, plist *Plist, freeProgs bool) { ...@@ -111,7 +117,7 @@ func flushplist(ctxt *Link, plist *Plist, freeProgs bool) {
} }
if !found { if !found {
p := Appendp(ctxt, s.Text) p := Appendp(s.Text, newprog)
p.As = AFUNCDATA p.As = AFUNCDATA
p.From.Type = TYPE_CONST p.From.Type = TYPE_CONST
p.From.Offset = FUNCDATA_ArgsPointerMaps p.From.Offset = FUNCDATA_ArgsPointerMaps
...@@ -124,9 +130,9 @@ func flushplist(ctxt *Link, plist *Plist, freeProgs bool) { ...@@ -124,9 +130,9 @@ func flushplist(ctxt *Link, plist *Plist, freeProgs bool) {
// Turn functions into machine code images. // Turn functions into machine code images.
for _, s := range text { for _, s := range text {
mkfwd(s) mkfwd(s)
linkpatch(ctxt, s) linkpatch(ctxt, s, newprog)
ctxt.Arch.Preprocess(ctxt, s) ctxt.Arch.Preprocess(ctxt, s, newprog)
ctxt.Arch.Assemble(ctxt, s) ctxt.Arch.Assemble(ctxt, s, newprog)
linkpcln(ctxt, s) linkpcln(ctxt, s)
makeFuncDebugEntry(ctxt, plist.Curfn, s) makeFuncDebugEntry(ctxt, plist.Curfn, s)
if freeProgs { if freeProgs {
......
...@@ -552,7 +552,7 @@ var oprange [ALAST & obj.AMask][]Optab ...@@ -552,7 +552,7 @@ var oprange [ALAST & obj.AMask][]Optab
var xcmp [C_NCLASS][C_NCLASS]bool var xcmp [C_NCLASS][C_NCLASS]bool
func span9(ctxt *obj.Link, cursym *obj.LSym) { func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p := cursym.Text p := cursym.Text
if p == nil || p.Link == nil { // handle external functions and ELF section symbols if p == nil || p.Link == nil { // handle external functions and ELF section symbols
return return
...@@ -609,14 +609,14 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -609,14 +609,14 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil { if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil {
otxt = p.Pcond.Pc - c otxt = p.Pcond.Pc - c
if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 { if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
q = ctxt.NewProg() q = newprog()
q.Link = p.Link q.Link = p.Link
p.Link = q p.Link = q
q.As = ABR q.As = ABR
q.To.Type = obj.TYPE_BRANCH q.To.Type = obj.TYPE_BRANCH
q.Pcond = p.Pcond q.Pcond = p.Pcond
p.Pcond = q p.Pcond = q
q = ctxt.NewProg() q = newprog()
q.Link = p.Link q.Link = p.Link
p.Link = q p.Link = q
q.As = ABR q.As = ABR
......
...@@ -36,7 +36,7 @@ import ( ...@@ -36,7 +36,7 @@ import (
"math" "math"
) )
func progedit(ctxt *obj.Link, p *obj.Prog) { func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
p.From.Class = 0 p.From.Class = 0
p.To.Class = 0 p.To.Class = 0
...@@ -116,12 +116,12 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { ...@@ -116,12 +116,12 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
} }
} }
if ctxt.Flag_dynlink { if ctxt.Flag_dynlink {
rewriteToUseGot(ctxt, p) rewriteToUseGot(ctxt, p, newprog)
} }
} }
// Rewrite p, if necessary, to access global data via the global offset table. // Rewrite p, if necessary, to access global data via the global offset table.
func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO { if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO {
// ADUFFxxx $offset // ADUFFxxx $offset
// becomes // becomes
...@@ -145,19 +145,19 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -145,19 +145,19 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
p.To.Name = obj.NAME_NONE p.To.Name = obj.NAME_NONE
p.To.Offset = 0 p.To.Offset = 0
p.To.Sym = nil p.To.Sym = nil
p1 := obj.Appendp(ctxt, p) p1 := obj.Appendp(p, newprog)
p1.As = AADD p1.As = AADD
p1.From.Type = obj.TYPE_CONST p1.From.Type = obj.TYPE_CONST
p1.From.Offset = offset p1.From.Offset = offset
p1.To.Type = obj.TYPE_REG p1.To.Type = obj.TYPE_REG
p1.To.Reg = REG_R12 p1.To.Reg = REG_R12
p2 := obj.Appendp(ctxt, p1) p2 := obj.Appendp(p1, newprog)
p2.As = AMOVD p2.As = AMOVD
p2.From.Type = obj.TYPE_REG p2.From.Type = obj.TYPE_REG
p2.From.Reg = REG_R12 p2.From.Reg = REG_R12
p2.To.Type = obj.TYPE_REG p2.To.Type = obj.TYPE_REG
p2.To.Reg = REG_CTR p2.To.Reg = REG_CTR
p3 := obj.Appendp(ctxt, p2) p3 := obj.Appendp(p2, newprog)
p3.As = obj.ACALL p3.As = obj.ACALL
p3.From.Type = obj.TYPE_REG p3.From.Type = obj.TYPE_REG
p3.From.Reg = REG_R12 p3.From.Reg = REG_R12
...@@ -180,7 +180,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -180,7 +180,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_GOTREF p.From.Name = obj.NAME_GOTREF
if p.From.Offset != 0 { if p.From.Offset != 0 {
q := obj.Appendp(ctxt, p) q := obj.Appendp(p, newprog)
q.As = AADD q.As = AADD
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = p.From.Offset q.From.Offset = p.From.Offset
...@@ -214,8 +214,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -214,8 +214,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
if source.Type != obj.TYPE_MEM { if source.Type != obj.TYPE_MEM {
ctxt.Diag("don't know how to handle %v with -dynlink", p) ctxt.Diag("don't know how to handle %v with -dynlink", p)
} }
p1 := obj.Appendp(ctxt, p) p1 := obj.Appendp(p, newprog)
p2 := obj.Appendp(ctxt, p1) p2 := obj.Appendp(p1, newprog)
p1.As = AMOVD p1.As = AMOVD
p1.From.Type = obj.TYPE_MEM p1.From.Type = obj.TYPE_MEM
...@@ -241,7 +241,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -241,7 +241,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
obj.Nopout(p) obj.Nopout(p)
} }
func preprocess(ctxt *obj.Link, cursym *obj.LSym) { func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
// TODO(minux): add morestack short-cuts with small fixed frame-size. // TODO(minux): add morestack short-cuts with small fixed frame-size.
ctxt.Cursym = cursym ctxt.Cursym = cursym
...@@ -491,12 +491,12 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -491,12 +491,12 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// generate the addis instruction except as part of the // generate the addis instruction except as part of the
// load of a large constant, and in that case there is no // load of a large constant, and in that case there is no
// way to use r12 as the source. // way to use r12 as the source.
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AWORD q.As = AWORD
q.Pos = p.Pos q.Pos = p.Pos
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = 0x3c4c0000 q.From.Offset = 0x3c4c0000
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AWORD q.As = AWORD
q.Pos = p.Pos q.Pos = p.Pos
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
...@@ -509,7 +509,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -509,7 +509,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
if cursym.Text.From3.Offset&obj.NOSPLIT == 0 { if cursym.Text.From3.Offset&obj.NOSPLIT == 0 {
q = stacksplit(ctxt, q, autosize) // emit split check q = stacksplit(ctxt, q, newprog, autosize) // emit split check
} }
if autosize != 0 { if autosize != 0 {
...@@ -517,7 +517,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -517,7 +517,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// it is a leaf function, so that traceback works. // it is a leaf function, so that traceback works.
if cursym.Text.Mark&LEAF == 0 && autosize >= -BIG && autosize <= BIG { if cursym.Text.Mark&LEAF == 0 && autosize >= -BIG && autosize <= BIG {
// Use MOVDU to adjust R1 when saving R31, if autosize is small. // Use MOVDU to adjust R1 when saving R31, if autosize is small.
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AMOVD q.As = AMOVD
q.Pos = p.Pos q.Pos = p.Pos
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
...@@ -525,7 +525,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -525,7 +525,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REGTMP q.To.Reg = REGTMP
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AMOVDU q.As = AMOVDU
q.Pos = p.Pos q.Pos = p.Pos
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
...@@ -539,7 +539,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -539,7 +539,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// Store link register before decrementing SP, so if a signal comes // Store link register before decrementing SP, so if a signal comes
// during the execution of the function prologue, the traceback // during the execution of the function prologue, the traceback
// code will not see a half-updated stack frame. // code will not see a half-updated stack frame.
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AMOVD q.As = AMOVD
q.Pos = p.Pos q.Pos = p.Pos
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
...@@ -547,7 +547,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -547,7 +547,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R29 // REGTMP may be used to synthesize large offset in the next instruction q.To.Reg = REG_R29 // REGTMP may be used to synthesize large offset in the next instruction
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AMOVD q.As = AMOVD
q.Pos = p.Pos q.Pos = p.Pos
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
...@@ -556,7 +556,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -556,7 +556,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Offset = int64(-autosize) q.To.Offset = int64(-autosize)
q.To.Reg = REGSP q.To.Reg = REGSP
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AADD q.As = AADD
q.Pos = p.Pos q.Pos = p.Pos
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
...@@ -578,7 +578,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -578,7 +578,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
if ctxt.Flag_shared { if ctxt.Flag_shared {
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AMOVD q.As = AMOVD
q.Pos = p.Pos q.Pos = p.Pos
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
...@@ -606,7 +606,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -606,7 +606,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// The NOP is needed to give the jumps somewhere to land. // 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. // It is a liblink NOP, not a ppc64 NOP: it encodes to 0 instruction bytes.
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AMOVD q.As = AMOVD
q.From.Type = obj.TYPE_MEM q.From.Type = obj.TYPE_MEM
...@@ -615,19 +615,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -615,19 +615,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R3 q.To.Reg = REG_R3
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = ACMP q.As = ACMP
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R0 q.From.Reg = REG_R0
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R3 q.To.Reg = REG_R3
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = ABEQ q.As = ABEQ
q.To.Type = obj.TYPE_BRANCH q.To.Type = obj.TYPE_BRANCH
p1 = q p1 = q
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AMOVD q.As = AMOVD
q.From.Type = obj.TYPE_MEM q.From.Type = obj.TYPE_MEM
q.From.Reg = REG_R3 q.From.Reg = REG_R3
...@@ -635,7 +635,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -635,7 +635,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R4 q.To.Reg = REG_R4
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AADD q.As = AADD
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(autosize) + ctxt.FixedFrameSize() q.From.Offset = int64(autosize) + ctxt.FixedFrameSize()
...@@ -643,19 +643,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -643,19 +643,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R5 q.To.Reg = REG_R5
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = ACMP q.As = ACMP
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R4 q.From.Reg = REG_R4
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R5 q.To.Reg = REG_R5
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = ABNE q.As = ABNE
q.To.Type = obj.TYPE_BRANCH q.To.Type = obj.TYPE_BRANCH
p2 = q p2 = q
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AADD q.As = AADD
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = ctxt.FixedFrameSize() q.From.Offset = ctxt.FixedFrameSize()
...@@ -663,7 +663,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -663,7 +663,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R6 q.To.Reg = REG_R6
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AMOVD q.As = AMOVD
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R6 q.From.Reg = REG_R6
...@@ -671,7 +671,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -671,7 +671,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Reg = REG_R3 q.To.Reg = REG_R3
q.To.Offset = 0 // Panic.argp q.To.Offset = 0 // Panic.argp
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = obj.ANOP q.As = obj.ANOP
p1.Pcond = q p1.Pcond = q
...@@ -708,7 +708,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -708,7 +708,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Reg = REGSP p.To.Reg = REGSP
p.Spadj = -autosize p.Spadj = -autosize
q = ctxt.NewProg() q = newprog()
q.As = ABR q.As = ABR
q.Pos = p.Pos q.Pos = p.Pos
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
...@@ -728,7 +728,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -728,7 +728,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REGTMP p.To.Reg = REGTMP
q = ctxt.NewProg() q = newprog()
q.As = AMOVD q.As = AMOVD
q.Pos = p.Pos q.Pos = p.Pos
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
...@@ -742,7 +742,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -742,7 +742,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
if false { if false {
// Debug bad returns // Debug bad returns
q = ctxt.NewProg() q = newprog()
q.As = AMOVD q.As = AMOVD
q.Pos = p.Pos q.Pos = p.Pos
...@@ -758,7 +758,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -758,7 +758,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
if autosize != 0 { if autosize != 0 {
q = ctxt.NewProg() q = newprog()
q.As = AADD q.As = AADD
q.Pos = p.Pos q.Pos = p.Pos
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
...@@ -771,7 +771,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -771,7 +771,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.Link = q p.Link = q
} }
q1 = ctxt.NewProg() q1 = newprog()
q1.As = ABR q1.As = ABR
q1.Pos = p.Pos q1.Pos = p.Pos
if retTarget == nil { if retTarget == nil {
...@@ -839,11 +839,11 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -839,11 +839,11 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q = p; q = p;
} }
*/ */
func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize int32) *obj.Prog {
p0 := p // save entry point, but skipping the two instructions setting R2 in shared mode p0 := p // save entry point, but skipping the two instructions setting R2 in shared mode
// MOVD g_stackguard(g), R3 // MOVD g_stackguard(g), R3
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVD p.As = AMOVD
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
...@@ -859,7 +859,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -859,7 +859,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
if framesize <= obj.StackSmall { if framesize <= obj.StackSmall {
// small stack: SP < stackguard // small stack: SP < stackguard
// CMP stackguard, SP // CMP stackguard, SP
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ACMPU p.As = ACMPU
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -870,7 +870,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -870,7 +870,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// large stack: SP-framesize < stackguard-StackSmall // large stack: SP-framesize < stackguard-StackSmall
// ADD $-(framesize-StackSmall), SP, R4 // ADD $-(framesize-StackSmall), SP, R4
// CMP stackguard, R4 // CMP stackguard, R4
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AADD p.As = AADD
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
...@@ -879,7 +879,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -879,7 +879,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4 p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ACMPU p.As = ACMPU
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3 p.From.Reg = REG_R3
...@@ -901,7 +901,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -901,7 +901,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// SUB R3, R4 // SUB R3, R4
// MOVD $(framesize+(StackGuard-StackSmall)), R31 // MOVD $(framesize+(StackGuard-StackSmall)), R31
// CMPU R31, R4 // CMPU R31, R4
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ACMP p.As = ACMP
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -909,12 +909,12 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -909,12 +909,12 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_CONST p.To.Type = obj.TYPE_CONST
p.To.Offset = obj.StackPreempt p.To.Offset = obj.StackPreempt
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
q = p q = p
p.As = ABEQ p.As = ABEQ
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AADD p.As = AADD
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = obj.StackGuard p.From.Offset = obj.StackGuard
...@@ -922,21 +922,21 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -922,21 +922,21 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4 p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ASUB p.As = ASUB
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3 p.From.Reg = REG_R3
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4 p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVD p.As = AMOVD
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REGTMP p.To.Reg = REGTMP
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ACMPU p.As = ACMPU
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REGTMP p.From.Reg = REGTMP
...@@ -945,14 +945,14 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -945,14 +945,14 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
} }
// q1: BLT done // q1: BLT done
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
q1 := p q1 := p
p.As = ABLT p.As = ABLT
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
// MOVD LR, R5 // MOVD LR, R5
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVD p.As = AMOVD
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -981,7 +981,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -981,7 +981,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// 24(SP) is caller's saved R2). Use 8(SP) to save this function's R2. // 24(SP) is caller's saved R2). Use 8(SP) to save this function's R2.
// MOVD R12, 8(SP) // MOVD R12, 8(SP)
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVD p.As = AMOVD
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R2 p.From.Reg = REG_R2
...@@ -1006,7 +1006,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -1006,7 +1006,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// seems preferable. // seems preferable.
// MOVD $runtime.morestack(SB), R12 // MOVD $runtime.morestack(SB), R12
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVD p.As = AMOVD
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
p.From.Sym = morestacksym p.From.Sym = morestacksym
...@@ -1015,7 +1015,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -1015,7 +1015,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Reg = REG_R12 p.To.Reg = REG_R12
// MOVD R12, CTR // MOVD R12, CTR
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVD p.As = AMOVD
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R12 p.From.Reg = REG_R12
...@@ -1023,7 +1023,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -1023,7 +1023,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Reg = REG_CTR p.To.Reg = REG_CTR
// BL CTR // BL CTR
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = obj.ACALL p.As = obj.ACALL
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R12 p.From.Reg = REG_R12
...@@ -1031,7 +1031,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -1031,7 +1031,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Reg = REG_CTR p.To.Reg = REG_CTR
} else { } else {
// BL runtime.morestack(SB) // BL runtime.morestack(SB)
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ABL p.As = ABL
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
...@@ -1040,7 +1040,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -1040,7 +1040,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
if ctxt.Flag_shared { if ctxt.Flag_shared {
// MOVD 8(SP), R2 // MOVD 8(SP), R2
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVD p.As = AMOVD
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
p.From.Reg = REGSP p.From.Reg = REGSP
...@@ -1050,13 +1050,13 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog { ...@@ -1050,13 +1050,13 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
} }
// BR start // BR start
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ABR p.As = ABR
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
p.Pcond = p0.Link p.Pcond = p0.Link
// placeholder for q1's jump target // placeholder for q1's jump target
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = obj.ANOP // zero-width place holder p.As = obj.ANOP // zero-width place holder
q1.Pcond = p q1.Pcond = p
......
...@@ -385,7 +385,7 @@ var oprange [ALAST & obj.AMask][]Optab ...@@ -385,7 +385,7 @@ var oprange [ALAST & obj.AMask][]Optab
var xcmp [C_NCLASS][C_NCLASS]bool var xcmp [C_NCLASS][C_NCLASS]bool
func spanz(ctxt *obj.Link, cursym *obj.LSym) { func spanz(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p := cursym.Text p := cursym.Text
if p == nil || p.Link == nil { // handle external functions and ELF section symbols if p == nil || p.Link == nil { // handle external functions and ELF section symbols
return return
......
...@@ -36,7 +36,7 @@ import ( ...@@ -36,7 +36,7 @@ import (
"math" "math"
) )
func progedit(ctxt *obj.Link, p *obj.Prog) { func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
p.From.Class = 0 p.From.Class = 0
p.To.Class = 0 p.To.Class = 0
...@@ -122,12 +122,12 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { ...@@ -122,12 +122,12 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
} }
if ctxt.Flag_dynlink { if ctxt.Flag_dynlink {
rewriteToUseGot(ctxt, p) rewriteToUseGot(ctxt, p, newprog)
} }
} }
// Rewrite p, if necessary, to access global data via the global offset table. // Rewrite p, if necessary, to access global data via the global offset table.
func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
// At the moment EXRL instructions are not emitted by the compiler and only reference local symbols in // At the moment EXRL instructions are not emitted by the compiler and only reference local symbols in
// assembly code. // assembly code.
if p.As == AEXRL { if p.As == AEXRL {
...@@ -147,7 +147,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -147,7 +147,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
p.From.Name = obj.NAME_GOTREF p.From.Name = obj.NAME_GOTREF
q := p q := p
if p.From.Offset != 0 { if p.From.Offset != 0 {
q = obj.Appendp(ctxt, p) q = obj.Appendp(p, newprog)
q.As = AADD q.As = AADD
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = p.From.Offset q.From.Offset = p.From.Offset
...@@ -181,8 +181,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -181,8 +181,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
if source.Type != obj.TYPE_MEM { if source.Type != obj.TYPE_MEM {
ctxt.Diag("don't know how to handle %v with -dynlink", p) ctxt.Diag("don't know how to handle %v with -dynlink", p)
} }
p1 := obj.Appendp(ctxt, p) p1 := obj.Appendp(p, newprog)
p2 := obj.Appendp(ctxt, p1) p2 := obj.Appendp(p1, newprog)
p1.As = AMOVD p1.As = AMOVD
p1.From.Type = obj.TYPE_MEM p1.From.Type = obj.TYPE_MEM
...@@ -208,7 +208,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -208,7 +208,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
obj.Nopout(p) obj.Nopout(p)
} }
func preprocess(ctxt *obj.Link, cursym *obj.LSym) { func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
// TODO(minux): add morestack short-cuts with small fixed frame-size. // TODO(minux): add morestack short-cuts with small fixed frame-size.
ctxt.Cursym = cursym ctxt.Cursym = cursym
...@@ -332,7 +332,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -332,7 +332,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q := p q := p
if p.From3.Offset&obj.NOSPLIT == 0 { if p.From3.Offset&obj.NOSPLIT == 0 {
p, pPreempt = stacksplitPre(ctxt, p, autosize) // emit pre part of split check p, pPreempt = stacksplitPre(ctxt, p, newprog, autosize) // emit pre part of split check
pPre = p pPre = p
wasSplit = true //need post part of split wasSplit = true //need post part of split
} }
...@@ -343,7 +343,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -343,7 +343,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// Store link register before decrementing SP, so if a signal comes // Store link register before decrementing SP, so if a signal comes
// during the execution of the function prologue, the traceback // during the execution of the function prologue, the traceback
// code will not see a half-updated stack frame. // code will not see a half-updated stack frame.
q = obj.Appendp(ctxt, p) q = obj.Appendp(p, newprog)
q.As = AMOVD q.As = AMOVD
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REG_LR q.From.Reg = REG_LR
...@@ -351,7 +351,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -351,7 +351,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Reg = REGSP q.To.Reg = REGSP
q.To.Offset = int64(-autosize) q.To.Offset = int64(-autosize)
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AMOVD q.As = AMOVD
q.From.Type = obj.TYPE_ADDR q.From.Type = obj.TYPE_ADDR
q.From.Offset = int64(-autosize) q.From.Offset = int64(-autosize)
...@@ -389,7 +389,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -389,7 +389,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// The NOP is needed to give the jumps somewhere to land. // 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. // It is a liblink NOP, not a s390x NOP: it encodes to 0 instruction bytes.
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AMOVD q.As = AMOVD
q.From.Type = obj.TYPE_MEM q.From.Type = obj.TYPE_MEM
...@@ -398,19 +398,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -398,19 +398,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R3 q.To.Reg = REG_R3
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = ACMP q.As = ACMP
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R3 q.From.Reg = REG_R3
q.To.Type = obj.TYPE_CONST q.To.Type = obj.TYPE_CONST
q.To.Offset = 0 q.To.Offset = 0
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = ABEQ q.As = ABEQ
q.To.Type = obj.TYPE_BRANCH q.To.Type = obj.TYPE_BRANCH
p1 := q p1 := q
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AMOVD q.As = AMOVD
q.From.Type = obj.TYPE_MEM q.From.Type = obj.TYPE_MEM
q.From.Reg = REG_R3 q.From.Reg = REG_R3
...@@ -418,7 +418,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -418,7 +418,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R4 q.To.Reg = REG_R4
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AADD q.As = AADD
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(autosize) + ctxt.FixedFrameSize() q.From.Offset = int64(autosize) + ctxt.FixedFrameSize()
...@@ -426,19 +426,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -426,19 +426,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R5 q.To.Reg = REG_R5
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = ACMP q.As = ACMP
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R4 q.From.Reg = REG_R4
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R5 q.To.Reg = REG_R5
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = ABNE q.As = ABNE
q.To.Type = obj.TYPE_BRANCH q.To.Type = obj.TYPE_BRANCH
p2 := q p2 := q
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AADD q.As = AADD
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = ctxt.FixedFrameSize() q.From.Offset = ctxt.FixedFrameSize()
...@@ -446,7 +446,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -446,7 +446,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R6 q.To.Reg = REG_R6
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AMOVD q.As = AMOVD
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R6 q.From.Reg = REG_R6
...@@ -454,7 +454,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -454,7 +454,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Reg = REG_R3 q.To.Reg = REG_R3
q.To.Offset = 0 // Panic.argp q.To.Offset = 0 // Panic.argp
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = obj.ANOP q.As = obj.ANOP
p1.Pcond = q p1.Pcond = q
...@@ -486,7 +486,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -486,7 +486,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Reg = REGSP p.To.Reg = REGSP
p.Spadj = -autosize p.Spadj = -autosize
q = obj.Appendp(ctxt, p) q = obj.Appendp(p, newprog)
q.As = ABR q.As = ABR
q.From = obj.Addr{} q.From = obj.Addr{}
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
...@@ -506,7 +506,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -506,7 +506,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q = p q = p
if autosize != 0 { if autosize != 0 {
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = AADD q.As = AADD
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(autosize) q.From.Offset = int64(autosize)
...@@ -515,7 +515,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -515,7 +515,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.Spadj = -autosize q.Spadj = -autosize
} }
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = ABR q.As = ABR
q.From = obj.Addr{} q.From = obj.Addr{}
if retTarget == nil { if retTarget == nil {
...@@ -535,15 +535,15 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -535,15 +535,15 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
} }
if wasSplit { if wasSplit {
stacksplitPost(ctxt, pLast, pPre, pPreempt, autosize) // emit post part of split check stacksplitPost(ctxt, pLast, pPre, pPreempt, newprog, autosize) // emit post part of split check
} }
} }
func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *obj.Prog) { func stacksplitPre(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize int32) (*obj.Prog, *obj.Prog) {
var q *obj.Prog var q *obj.Prog
// MOVD g_stackguard(g), R3 // MOVD g_stackguard(g), R3
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVD p.As = AMOVD
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
...@@ -565,7 +565,7 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob ...@@ -565,7 +565,7 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob
// q1: BLT done // q1: BLT done
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
//q1 = p //q1 = p
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3 p.From.Reg = REG_R3
...@@ -588,7 +588,7 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob ...@@ -588,7 +588,7 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob
// large stack: SP-framesize < stackguard-StackSmall // large stack: SP-framesize < stackguard-StackSmall
// ADD $-(framesize-StackSmall), SP, R4 // ADD $-(framesize-StackSmall), SP, R4
// CMP stackguard, R4 // CMP stackguard, R4
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AADD p.As = AADD
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
...@@ -597,7 +597,7 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob ...@@ -597,7 +597,7 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4 p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3 p.From.Reg = REG_R3
p.Reg = REG_R4 p.Reg = REG_R4
...@@ -620,7 +620,7 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob ...@@ -620,7 +620,7 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob
// SUB R3, R4 // SUB R3, R4
// MOVD $(framesize+(StackGuard-StackSmall)), TEMP // MOVD $(framesize+(StackGuard-StackSmall)), TEMP
// CMPUBGE TEMP, R4 // CMPUBGE TEMP, R4
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ACMP p.As = ACMP
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -628,12 +628,12 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob ...@@ -628,12 +628,12 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob
p.To.Type = obj.TYPE_CONST p.To.Type = obj.TYPE_CONST
p.To.Offset = obj.StackPreempt p.To.Offset = obj.StackPreempt
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
q = p q = p
p.As = ABEQ p.As = ABEQ
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AADD p.As = AADD
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = obj.StackGuard p.From.Offset = obj.StackGuard
...@@ -641,21 +641,21 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob ...@@ -641,21 +641,21 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4 p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ASUB p.As = ASUB
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3 p.From.Reg = REG_R3
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4 p.To.Reg = REG_R4
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVD p.As = AMOVD
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REGTMP p.To.Reg = REGTMP
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REGTMP p.From.Reg = REGTMP
p.Reg = REG_R4 p.Reg = REG_R4
...@@ -666,15 +666,15 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob ...@@ -666,15 +666,15 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob
return p, q return p, q
} }
func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.Prog, framesize int32) *obj.Prog { func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.Prog, newprog obj.ProgAlloc, framesize int32) *obj.Prog {
// Now we are at the end of the function, but logically // Now we are at the end of the function, but logically
// we are still in function prologue. We need to fix the // we are still in function prologue. We need to fix the
// SP data and PCDATA. // SP data and PCDATA.
spfix := obj.Appendp(ctxt, p) spfix := obj.Appendp(p, newprog)
spfix.As = obj.ANOP spfix.As = obj.ANOP
spfix.Spadj = -framesize spfix.Spadj = -framesize
pcdata := obj.Appendp(ctxt, spfix) pcdata := obj.Appendp(spfix, newprog)
pcdata.Pos = ctxt.Cursym.Text.Pos pcdata.Pos = ctxt.Cursym.Text.Pos
pcdata.As = obj.APCDATA pcdata.As = obj.APCDATA
pcdata.From.Type = obj.TYPE_CONST pcdata.From.Type = obj.TYPE_CONST
...@@ -683,7 +683,7 @@ func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.P ...@@ -683,7 +683,7 @@ func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.P
pcdata.To.Offset = -1 // pcdata starts at -1 at function entry pcdata.To.Offset = -1 // pcdata starts at -1 at function entry
// MOVD LR, R5 // MOVD LR, R5
p = obj.Appendp(ctxt, pcdata) p = obj.Appendp(pcdata, newprog)
pPre.Pcond = p pPre.Pcond = p
p.As = AMOVD p.As = AMOVD
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -695,7 +695,7 @@ func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.P ...@@ -695,7 +695,7 @@ func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.P
} }
// BL runtime.morestack(SB) // BL runtime.morestack(SB)
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ABL p.As = ABL
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
...@@ -708,7 +708,7 @@ func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.P ...@@ -708,7 +708,7 @@ func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.P
} }
// BR start // BR start
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ABR p.As = ABR
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
......
...@@ -1762,7 +1762,7 @@ func spadjop(ctxt *obj.Link, p *obj.Prog, l, q obj.As) obj.As { ...@@ -1762,7 +1762,7 @@ func spadjop(ctxt *obj.Link, p *obj.Prog, l, q obj.As) obj.As {
return q return q
} }
func span6(ctxt *obj.Link, s *obj.LSym) { func span6(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
if s.P != nil { if s.P != nil {
return return
} }
......
...@@ -71,7 +71,7 @@ func CanUse1InsnTLS(ctxt *obj.Link) bool { ...@@ -71,7 +71,7 @@ func CanUse1InsnTLS(ctxt *obj.Link) bool {
return true return true
} }
func progedit(ctxt *obj.Link, p *obj.Prog) { func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
// Thread-local storage references use the TLS pseudo-register. // Thread-local storage references use the TLS pseudo-register.
// As a register, TLS refers to the thread-local storage base, and it // As a register, TLS refers to the thread-local storage base, and it
// can only be loaded into another register: // can only be loaded into another register:
...@@ -146,7 +146,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { ...@@ -146,7 +146,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
// MOVQ TLS, BX // MOVQ TLS, BX
// MOVQ 0(BX)(TLS*1), BX // MOVQ 0(BX)(TLS*1), BX
if (p.As == AMOVQ || p.As == AMOVL) && p.From.Type == obj.TYPE_MEM && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 { if (p.As == AMOVQ || p.As == AMOVL) && p.From.Type == obj.TYPE_MEM && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 {
q := obj.Appendp(ctxt, p) q := obj.Appendp(p, newprog)
q.As = p.As q.As = p.As
q.From = p.From q.From = p.From
q.From.Type = obj.TYPE_MEM q.From.Type = obj.TYPE_MEM
...@@ -293,16 +293,16 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { ...@@ -293,16 +293,16 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
} }
if ctxt.Flag_dynlink { if ctxt.Flag_dynlink {
rewriteToUseGot(ctxt, p) rewriteToUseGot(ctxt, p, newprog)
} }
if ctxt.Flag_shared && ctxt.Arch.Family == sys.I386 { if ctxt.Flag_shared && ctxt.Arch.Family == sys.I386 {
rewriteToPcrel(ctxt, p) rewriteToPcrel(ctxt, p, newprog)
} }
} }
// Rewrite p, if necessary, to access global data via the global offset table. // Rewrite p, if necessary, to access global data via the global offset table.
func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
var add, lea, mov obj.As var add, lea, mov obj.As
var reg int16 var reg int16
if ctxt.Arch.Family == sys.AMD64 { if ctxt.Arch.Family == sys.AMD64 {
...@@ -345,13 +345,13 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -345,13 +345,13 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
p.To.Reg = reg p.To.Reg = reg
p.To.Offset = 0 p.To.Offset = 0
p.To.Sym = nil p.To.Sym = nil
p1 := obj.Appendp(ctxt, p) p1 := obj.Appendp(p, newprog)
p1.As = add p1.As = add
p1.From.Type = obj.TYPE_CONST p1.From.Type = obj.TYPE_CONST
p1.From.Offset = offset p1.From.Offset = offset
p1.To.Type = obj.TYPE_REG p1.To.Type = obj.TYPE_REG
p1.To.Reg = reg p1.To.Reg = reg
p2 := obj.Appendp(ctxt, p1) p2 := obj.Appendp(p1, newprog)
p2.As = obj.ACALL p2.As = obj.ACALL
p2.To.Type = obj.TYPE_REG p2.To.Type = obj.TYPE_REG
p2.To.Reg = reg p2.To.Reg = reg
...@@ -388,7 +388,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -388,7 +388,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
p.From.Name = obj.NAME_GOTREF p.From.Name = obj.NAME_GOTREF
q := p q := p
if p.From.Offset != 0 { if p.From.Offset != 0 {
q = obj.Appendp(ctxt, p) q = obj.Appendp(p, newprog)
q.As = lea q.As = lea
q.From.Type = obj.TYPE_MEM q.From.Type = obj.TYPE_MEM
q.From.Reg = p.To.Reg q.From.Reg = p.To.Reg
...@@ -397,7 +397,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -397,7 +397,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
p.From.Offset = 0 p.From.Offset = 0
} }
if cmplxdest { if cmplxdest {
q = obj.Appendp(ctxt, q) q = obj.Appendp(q, newprog)
q.As = pAs q.As = pAs
q.To = dest q.To = dest
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
...@@ -429,8 +429,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -429,8 +429,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
if ctxt.Arch.Family == sys.AMD64 || (p.To.Sym != nil && p.To.Sym.Local()) || p.RegTo2 != 0 { if ctxt.Arch.Family == sys.AMD64 || (p.To.Sym != nil && p.To.Sym.Local()) || p.RegTo2 != 0 {
return return
} }
p1 := obj.Appendp(ctxt, p) p1 := obj.Appendp(p, newprog)
p2 := obj.Appendp(ctxt, p1) p2 := obj.Appendp(p1, newprog)
p1.As = ALEAL p1.As = ALEAL
p1.From.Type = obj.TYPE_MEM p1.From.Type = obj.TYPE_MEM
...@@ -461,8 +461,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -461,8 +461,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
if source.Type != obj.TYPE_MEM { if source.Type != obj.TYPE_MEM {
ctxt.Diag("don't know how to handle %v with -dynlink", p) ctxt.Diag("don't know how to handle %v with -dynlink", p)
} }
p1 := obj.Appendp(ctxt, p) p1 := obj.Appendp(p, newprog)
p2 := obj.Appendp(ctxt, p1) p2 := obj.Appendp(p1, newprog)
p1.As = mov p1.As = mov
p1.From.Type = obj.TYPE_MEM p1.From.Type = obj.TYPE_MEM
...@@ -488,7 +488,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) { ...@@ -488,7 +488,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
obj.Nopout(p) obj.Nopout(p)
} }
func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog) { func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
// RegTo2 is set on the instructions we insert here so they don't get // RegTo2 is set on the instructions we insert here so they don't get
// processed twice. // processed twice.
if p.RegTo2 != 0 { if p.RegTo2 != 0 {
...@@ -515,7 +515,7 @@ func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog) { ...@@ -515,7 +515,7 @@ func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog) {
// to "MOVL $sym, CX; MOVL CX, (SP)" or "MOVL $sym, CX; PUSHL CX" // to "MOVL $sym, CX; MOVL CX, (SP)" or "MOVL $sym, CX; PUSHL CX"
// respectively. // respectively.
if p.To.Type != obj.TYPE_REG { if p.To.Type != obj.TYPE_REG {
q := obj.Appendp(ctxt, p) q := obj.Appendp(p, newprog)
q.As = p.As q.As = p.As
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REG_CX q.From.Reg = REG_CX
...@@ -537,9 +537,9 @@ func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog) { ...@@ -537,9 +537,9 @@ func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog) {
// Why? See the comment near the top of rewriteToUseGot above. // Why? See the comment near the top of rewriteToUseGot above.
// AMOVLs might be introduced by the GOT rewrites. // AMOVLs might be introduced by the GOT rewrites.
} }
q := obj.Appendp(ctxt, p) q := obj.Appendp(p, newprog)
q.RegTo2 = 1 q.RegTo2 = 1
r := obj.Appendp(ctxt, q) r := obj.Appendp(q, newprog)
r.RegTo2 = 1 r.RegTo2 = 1
q.As = obj.ACALL q.As = obj.ACALL
q.To.Sym = obj.Linklookup(ctxt, "__x86.get_pc_thunk."+strings.ToLower(rconv(int(dst))), 0) q.To.Sym = obj.Linklookup(ctxt, "__x86.get_pc_thunk."+strings.ToLower(rconv(int(dst))), 0)
...@@ -596,7 +596,7 @@ func nacladdr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { ...@@ -596,7 +596,7 @@ func nacladdr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
} }
} }
func preprocess(ctxt *obj.Link, cursym *obj.LSym) { func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
if ctxt.Headtype == obj.Hplan9 && ctxt.Plan9privates == nil { if ctxt.Headtype == obj.Hplan9 && ctxt.Plan9privates == nil {
ctxt.Plan9privates = obj.Linklookup(ctxt, "_privates", 0) ctxt.Plan9privates = obj.Linklookup(ctxt, "_privates", 0)
} }
...@@ -676,19 +676,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -676,19 +676,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
if p.From3Offset()&obj.NOSPLIT == 0 || p.From3Offset()&obj.WRAPPER != 0 { if p.From3Offset()&obj.NOSPLIT == 0 || p.From3Offset()&obj.WRAPPER != 0 {
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p = load_g_cx(ctxt, p) // load g into CX p = load_g_cx(ctxt, p, newprog) // load g into CX
} }
if cursym.Text.From3Offset()&obj.NOSPLIT == 0 { if cursym.Text.From3Offset()&obj.NOSPLIT == 0 {
p = stacksplit(ctxt, cursym, p, autoffset, int32(textarg)) // emit split check p = stacksplit(ctxt, cursym, p, newprog, autoffset, int32(textarg)) // emit split check
} }
if autoffset != 0 { if autoffset != 0 {
if autoffset%int32(ctxt.Arch.RegSize) != 0 { if autoffset%int32(ctxt.Arch.RegSize) != 0 {
ctxt.Diag("unaligned stack size %d", autoffset) ctxt.Diag("unaligned stack size %d", autoffset)
} }
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AADJSP p.As = AADJSP
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(autoffset) p.From.Offset = int64(autoffset)
...@@ -699,7 +699,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -699,7 +699,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
if bpsize > 0 { if bpsize > 0 {
// Save caller's BP // Save caller's BP
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVQ p.As = AMOVQ
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -710,7 +710,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -710,7 +710,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Offset = int64(autoffset) - int64(bpsize) p.To.Offset = int64(autoffset) - int64(bpsize)
// Move current frame to BP // Move current frame to BP
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ALEAQ p.As = ALEAQ
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
...@@ -746,7 +746,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -746,7 +746,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// Both conditional jumps are unlikely, so they are arranged to be forward jumps. // Both conditional jumps are unlikely, so they are arranged to be forward jumps.
// MOVQ g_panic(CX), BX // MOVQ g_panic(CX), BX
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVQ p.As = AMOVQ
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
p.From.Reg = REG_CX p.From.Reg = REG_CX
...@@ -765,7 +765,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -765,7 +765,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
// TESTQ BX, BX // TESTQ BX, BX
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ATESTQ p.As = ATESTQ
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_BX p.From.Reg = REG_BX
...@@ -776,13 +776,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -776,13 +776,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
// JNE checkargp (checkargp to be resolved later) // JNE checkargp (checkargp to be resolved later)
jne := obj.Appendp(ctxt, p) jne := obj.Appendp(p, newprog)
jne.As = AJNE jne.As = AJNE
jne.To.Type = obj.TYPE_BRANCH jne.To.Type = obj.TYPE_BRANCH
// end: // end:
// NOP // NOP
end := obj.Appendp(ctxt, jne) end := obj.Appendp(jne, newprog)
end.As = obj.ANOP end.As = obj.ANOP
// Fast forward to end of function. // Fast forward to end of function.
...@@ -791,7 +791,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -791,7 +791,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
// LEAQ (autoffset+8)(SP), DI // LEAQ (autoffset+8)(SP), DI
p = obj.Appendp(ctxt, last) p = obj.Appendp(last, newprog)
p.As = ALEAQ p.As = ALEAQ
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
p.From.Reg = REG_SP p.From.Reg = REG_SP
...@@ -806,7 +806,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -806,7 +806,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
jne.Pcond = p jne.Pcond = p
// CMPQ panic_argp(BX), DI // CMPQ panic_argp(BX), DI
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = ACMPQ p.As = ACMPQ
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
p.From.Reg = REG_BX p.From.Reg = REG_BX
...@@ -825,13 +825,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -825,13 +825,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
// JNE end // JNE end
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AJNE p.As = AJNE
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
p.Pcond = end p.Pcond = end
// MOVQ SP, panic_argp(BX) // MOVQ SP, panic_argp(BX)
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AMOVQ p.As = AMOVQ
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_SP p.From.Reg = REG_SP
...@@ -850,7 +850,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -850,7 +850,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
} }
// JMP end // JMP end
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = obj.AJMP p.As = obj.AJMP
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
p.Pcond = end p.Pcond = end
...@@ -935,14 +935,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) { ...@@ -935,14 +935,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.From.Offset = int64(autoffset) - int64(bpsize) p.From.Offset = int64(autoffset) - int64(bpsize)
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_BP p.To.Reg = REG_BP
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
} }
p.As = AADJSP p.As = AADJSP
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(-autoffset) p.From.Offset = int64(-autoffset)
p.Spadj = -autoffset p.Spadj = -autoffset
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = obj.ARET p.As = obj.ARET
// If there are instructions following // If there are instructions following
...@@ -987,7 +987,7 @@ func indir_cx(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { ...@@ -987,7 +987,7 @@ func indir_cx(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
// Overwriting p is unusual but it lets use this in both the // Overwriting p is unusual but it lets use this in both the
// prologue (caller must call appendp first) and in the epilogue. // prologue (caller must call appendp first) and in the epilogue.
// Returns last new instruction. // Returns last new instruction.
func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog { func load_g_cx(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) *obj.Prog {
p.As = AMOVQ p.As = AMOVQ
if ctxt.Arch.PtrSize == 4 { if ctxt.Arch.PtrSize == 4 {
p.As = AMOVL p.As = AMOVL
...@@ -999,7 +999,7 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog { ...@@ -999,7 +999,7 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
p.To.Reg = REG_CX p.To.Reg = REG_CX
next := p.Link next := p.Link
progedit(ctxt, p) progedit(ctxt, p, newprog)
for p.Link != next { for p.Link != next {
p = p.Link p = p.Link
} }
...@@ -1015,7 +1015,7 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog { ...@@ -1015,7 +1015,7 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
// Appends to (does not overwrite) p. // Appends to (does not overwrite) p.
// Assumes g is in CX. // Assumes g is in CX.
// Returns last new instruction. // Returns last new instruction.
func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32, textarg int32) *obj.Prog { func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgAlloc, framesize int32, textarg int32) *obj.Prog {
cmp := ACMPQ cmp := ACMPQ
lea := ALEAQ lea := ALEAQ
mov := AMOVQ mov := AMOVQ
...@@ -1032,7 +1032,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32, ...@@ -1032,7 +1032,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32,
if framesize <= obj.StackSmall { if framesize <= obj.StackSmall {
// small stack: SP <= stackguard // small stack: SP <= stackguard
// CMPQ SP, stackguard // CMPQ SP, stackguard
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = cmp p.As = cmp
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
...@@ -1046,7 +1046,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32, ...@@ -1046,7 +1046,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32,
// large stack: SP-framesize <= stackguard-StackSmall // large stack: SP-framesize <= stackguard-StackSmall
// LEAQ -xxx(SP), AX // LEAQ -xxx(SP), AX
// CMPQ AX, stackguard // CMPQ AX, stackguard
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = lea p.As = lea
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
...@@ -1055,7 +1055,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32, ...@@ -1055,7 +1055,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32,
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_AX p.To.Reg = REG_AX
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = cmp p.As = cmp
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_AX p.From.Reg = REG_AX
...@@ -1080,7 +1080,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32, ...@@ -1080,7 +1080,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32,
// SUBQ CX, AX // SUBQ CX, AX
// CMPQ AX, $(framesize+(StackGuard-StackSmall)) // CMPQ AX, $(framesize+(StackGuard-StackSmall))
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = mov p.As = mov
indir_cx(ctxt, p, &p.From) indir_cx(ctxt, p, &p.From)
...@@ -1091,7 +1091,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32, ...@@ -1091,7 +1091,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32,
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_SI p.To.Reg = REG_SI
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = cmp p.As = cmp
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_SI p.From.Reg = REG_SI
...@@ -1101,12 +1101,12 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32, ...@@ -1101,12 +1101,12 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32,
p.To.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1))) p.To.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1)))
} }
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = AJEQ p.As = AJEQ
p.To.Type = obj.TYPE_BRANCH p.To.Type = obj.TYPE_BRANCH
q1 = p q1 = p
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = lea p.As = lea
p.From.Type = obj.TYPE_MEM p.From.Type = obj.TYPE_MEM
p.From.Reg = REG_SP p.From.Reg = REG_SP
...@@ -1114,14 +1114,14 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32, ...@@ -1114,14 +1114,14 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32,
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_AX p.To.Reg = REG_AX
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = sub p.As = sub
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_SI p.From.Reg = REG_SI
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_AX p.To.Reg = REG_AX
p = obj.Appendp(ctxt, p) p = obj.Appendp(p, newprog)
p.As = cmp p.As = cmp
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_AX p.From.Reg = REG_AX
...@@ -1130,7 +1130,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32, ...@@ -1130,7 +1130,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32,
} }
// common // common
jls := obj.Appendp(ctxt, p) jls := obj.Appendp(p, newprog)
jls.As = AJLS jls.As = AJLS
jls.To.Type = obj.TYPE_BRANCH jls.To.Type = obj.TYPE_BRANCH
...@@ -1141,11 +1141,11 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32, ...@@ -1141,11 +1141,11 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32,
// Now we are at the end of the function, but logically // Now we are at the end of the function, but logically
// we are still in function prologue. We need to fix the // we are still in function prologue. We need to fix the
// SP data and PCDATA. // SP data and PCDATA.
spfix := obj.Appendp(ctxt, last) spfix := obj.Appendp(last, newprog)
spfix.As = obj.ANOP spfix.As = obj.ANOP
spfix.Spadj = -framesize spfix.Spadj = -framesize
pcdata := obj.Appendp(ctxt, spfix) pcdata := obj.Appendp(spfix, newprog)
pcdata.Pos = cursym.Text.Pos pcdata.Pos = cursym.Text.Pos
pcdata.As = obj.APCDATA pcdata.As = obj.APCDATA
pcdata.From.Type = obj.TYPE_CONST pcdata.From.Type = obj.TYPE_CONST
...@@ -1153,7 +1153,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32, ...@@ -1153,7 +1153,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32,
pcdata.To.Type = obj.TYPE_CONST pcdata.To.Type = obj.TYPE_CONST
pcdata.To.Offset = -1 // pcdata starts at -1 at function entry pcdata.To.Offset = -1 // pcdata starts at -1 at function entry
call := obj.Appendp(ctxt, pcdata) call := obj.Appendp(pcdata, newprog)
call.Pos = cursym.Text.Pos call.Pos = cursym.Text.Pos
call.As = obj.ACALL call.As = obj.ACALL
call.To.Type = obj.TYPE_BRANCH call.To.Type = obj.TYPE_BRANCH
...@@ -1171,12 +1171,12 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32, ...@@ -1171,12 +1171,12 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32,
// to keep track of the start of the call (where the jump will be to) and the // to keep track of the start of the call (where the jump will be to) and the
// end (which following instructions are appended to). // end (which following instructions are appended to).
callend := call callend := call
progedit(ctxt, callend) progedit(ctxt, callend, newprog)
for ; callend.Link != nil; callend = callend.Link { for ; callend.Link != nil; callend = callend.Link {
progedit(ctxt, callend.Link) progedit(ctxt, callend.Link, newprog)
} }
jmp := obj.Appendp(ctxt, callend) jmp := obj.Appendp(callend, newprog)
jmp.As = obj.AJMP jmp.As = obj.AJMP
jmp.To.Type = obj.TYPE_BRANCH jmp.To.Type = obj.TYPE_BRANCH
jmp.Pcond = cursym.Text.Link jmp.Pcond = cursym.Text.Link
......
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