mirror of
https://github.com/golang/go.git
synced 2025-05-29 03:11:26 +00:00
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: Keith Randall <khr@golang.org>
This commit is contained in:
parent
7e068895c3
commit
5b59b32c97
@ -279,7 +279,7 @@ var deferreturn *obj.LSym
|
||||
// p->pc if extra padding is necessary.
|
||||
// In rare cases, asmoutnacl might split p into two instructions.
|
||||
// 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)
|
||||
|
||||
// instruction specific
|
||||
@ -406,7 +406,7 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3
|
||||
// split it into two instructions:
|
||||
// ADD $-100004, R13
|
||||
// MOVW R14, 0(R13)
|
||||
q := ctxt.NewProg()
|
||||
q := newprog()
|
||||
|
||||
p.Scond &^= C_WBIT
|
||||
*q = *p
|
||||
@ -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 {
|
||||
ctxt.Diag("unsupported instruction (.P/.W): %v", p)
|
||||
}
|
||||
q := ctxt.NewProg()
|
||||
q := newprog()
|
||||
*q = *p
|
||||
var a2 *obj.Addr
|
||||
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
|
||||
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 op *obj.Prog
|
||||
|
||||
@ -572,7 +572,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
var o *Optab
|
||||
for ; p != nil || ctxt.Blitrl != nil; op, p = p, p.Link {
|
||||
if p == nil {
|
||||
if checkpool(ctxt, op, 0) {
|
||||
if checkpool(ctxt, newprog, op, 0) {
|
||||
p = op
|
||||
continue
|
||||
}
|
||||
@ -588,7 +588,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
if ctxt.Headtype != obj.Hnacl {
|
||||
m = int(o.size)
|
||||
} 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
|
||||
o = oplook(ctxt, p) // asmoutnacl might change p in rare cases
|
||||
}
|
||||
@ -600,7 +600,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
// must check literal pool here in case p generates many instructions
|
||||
if ctxt.Blitrl != nil {
|
||||
i = m
|
||||
if checkpool(ctxt, op, i) {
|
||||
if checkpool(ctxt, newprog, op, i) {
|
||||
p = op
|
||||
continue
|
||||
}
|
||||
@ -613,19 +613,19 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
|
||||
switch o.flag & (LFROM | LTO | LPOOL) {
|
||||
case LFROM:
|
||||
addpool(ctxt, p, &p.From)
|
||||
addpool(ctxt, newprog, p, &p.From)
|
||||
|
||||
case LTO:
|
||||
addpool(ctxt, p, &p.To)
|
||||
addpool(ctxt, newprog, p, &p.To)
|
||||
|
||||
case LPOOL:
|
||||
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 {
|
||||
flushpool(ctxt, p, 0, 0)
|
||||
flushpool(ctxt, newprog, p, 0, 0)
|
||||
}
|
||||
c += int32(m)
|
||||
}
|
||||
@ -685,7 +685,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
if ctxt.Headtype != obj.Hnacl {
|
||||
m = int(o.size)
|
||||
} else {
|
||||
m = asmoutnacl(ctxt, c, p, o, nil)
|
||||
m = asmoutnacl(ctxt, newprog, c, p, o, nil)
|
||||
}
|
||||
if p.Pc != int64(opc) {
|
||||
bflag = 1
|
||||
@ -746,7 +746,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
asmout(ctxt, p, o, out[:])
|
||||
m = int(o.size)
|
||||
} else {
|
||||
m = asmoutnacl(ctxt, c, p, o, out[:])
|
||||
m = asmoutnacl(ctxt, newprog, c, p, o, out[:])
|
||||
if int64(opc) != p.Pc {
|
||||
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) {
|
||||
* drop the pool now, and branch round it.
|
||||
* 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 {
|
||||
return flushpool(ctxt, p, 1, 0)
|
||||
return flushpool(ctxt, newprog, p, 1, 0)
|
||||
} else if p.Link == nil {
|
||||
return flushpool(ctxt, p, 2, 0)
|
||||
return flushpool(ctxt, newprog, p, 2, 0)
|
||||
}
|
||||
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 skip != 0 {
|
||||
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)
|
||||
}
|
||||
q := ctxt.NewProg()
|
||||
q := newprog()
|
||||
q.As = AB
|
||||
q.To.Type = obj.TYPE_BRANCH
|
||||
q.Pcond = p.Link
|
||||
@ -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 pool is not multiple of 16 bytes, add an alignment marker
|
||||
q := ctxt.NewProg()
|
||||
q := newprog()
|
||||
|
||||
q.As = ADATABUNDLEEND
|
||||
ctxt.Elitrl.Link = q
|
||||
@ -850,7 +850,7 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int, force int) bool {
|
||||
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
|
||||
|
||||
c := aclass(ctxt, a)
|
||||
@ -894,7 +894,7 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
|
||||
|
||||
if ctxt.Headtype == obj.Hnacl && pool.size%16 == 0 {
|
||||
// start a new data bundle
|
||||
q := ctxt.NewProg()
|
||||
q := newprog()
|
||||
q.As = ADATABUNDLE
|
||||
q.Pc = int64(pool.size)
|
||||
pool.size += 4
|
||||
@ -908,7 +908,7 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
|
||||
ctxt.Elitrl = q
|
||||
}
|
||||
|
||||
q := ctxt.NewProg()
|
||||
q := newprog()
|
||||
*q = t
|
||||
q.Pc = int64(pool.size)
|
||||
|
||||
|
@ -39,7 +39,7 @@ import (
|
||||
|
||||
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.To.Class = 0
|
||||
|
||||
@ -80,7 +80,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||
p.To.Reg = REGTMP
|
||||
|
||||
// BL runtime.read_tls_fallback(SB)
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = ABL
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
@ -88,7 +88,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||
p.To.Offset = 0
|
||||
|
||||
// MOVW R11, LR
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = AMOVW
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -130,12 +130,12 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||
}
|
||||
|
||||
if ctxt.Flag_dynlink {
|
||||
rewriteToUseGot(ctxt, p)
|
||||
rewriteToUseGot(ctxt, p, newprog)
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// ADUFFxxx $offset
|
||||
// becomes
|
||||
@ -158,13 +158,13 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
p.To.Name = obj.NAME_NONE
|
||||
p.To.Offset = 0
|
||||
p.To.Sym = nil
|
||||
p1 := obj.Appendp(ctxt, p)
|
||||
p1 := obj.Appendp(p, newprog)
|
||||
p1.As = AADD
|
||||
p1.From.Type = obj.TYPE_CONST
|
||||
p1.From.Offset = offset
|
||||
p1.To.Type = obj.TYPE_REG
|
||||
p1.To.Reg = REG_R9
|
||||
p2 := obj.Appendp(ctxt, p1)
|
||||
p2 := obj.Appendp(p1, newprog)
|
||||
p2.As = obj.ACALL
|
||||
p2.To.Type = obj.TYPE_MEM
|
||||
p2.To.Reg = REG_R9
|
||||
@ -186,7 +186,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Name = obj.NAME_GOTREF
|
||||
if p.From.Offset != 0 {
|
||||
q := obj.Appendp(ctxt, p)
|
||||
q := obj.Appendp(p, newprog)
|
||||
q.As = AADD
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = p.From.Offset
|
||||
@ -220,8 +220,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
if source.Type != obj.TYPE_MEM {
|
||||
ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
||||
}
|
||||
p1 := obj.Appendp(ctxt, p)
|
||||
p2 := obj.Appendp(ctxt, p1)
|
||||
p1 := obj.Appendp(p, newprog)
|
||||
p2 := obj.Appendp(p1, newprog)
|
||||
|
||||
p1.As = AMOVW
|
||||
p1.From.Type = obj.TYPE_MEM
|
||||
@ -254,7 +254,7 @@ const (
|
||||
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)
|
||||
|
||||
ctxt.Cursym = cursym
|
||||
@ -263,7 +263,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
return
|
||||
}
|
||||
|
||||
softfloat(ctxt, cursym)
|
||||
softfloat(ctxt, newprog, cursym)
|
||||
|
||||
p := cursym.Text
|
||||
autoffset := int32(p.To.Offset)
|
||||
@ -370,11 +370,11 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
|
||||
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)
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = AMOVW
|
||||
p.Scond |= C_WBIT
|
||||
@ -406,7 +406,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
// 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.
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AMOVW
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Reg = REGG
|
||||
@ -414,19 +414,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R1
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ACMP
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = 0
|
||||
p.Reg = REG_R1
|
||||
|
||||
// B.NE checkargp
|
||||
bne := obj.Appendp(ctxt, p)
|
||||
bne := obj.Appendp(p, newprog)
|
||||
bne.As = ABNE
|
||||
bne.To.Type = obj.TYPE_BRANCH
|
||||
|
||||
// end: NOP
|
||||
end := obj.Appendp(ctxt, bne)
|
||||
end := obj.Appendp(bne, newprog)
|
||||
end.As = obj.ANOP
|
||||
|
||||
// find end of function
|
||||
@ -435,7 +435,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
|
||||
// MOVW panic_argp(R1), R2
|
||||
mov := obj.Appendp(ctxt, last)
|
||||
mov := obj.Appendp(last, newprog)
|
||||
mov.As = AMOVW
|
||||
mov.From.Type = obj.TYPE_MEM
|
||||
mov.From.Reg = REG_R1
|
||||
@ -447,7 +447,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
bne.Pcond = mov
|
||||
|
||||
// ADD $(autosize+4), R13, R3
|
||||
p = obj.Appendp(ctxt, mov)
|
||||
p = obj.Appendp(mov, newprog)
|
||||
p.As = AADD
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = int64(autosize) + 4
|
||||
@ -456,20 +456,20 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.To.Reg = REG_R3
|
||||
|
||||
// CMP R2, R3
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ACMP
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R2
|
||||
p.Reg = REG_R3
|
||||
|
||||
// B.NE end
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ABNE
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
p.Pcond = end
|
||||
|
||||
// ADD $4, R13, R4
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AADD
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = 4
|
||||
@ -478,7 +478,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.To.Reg = REG_R4
|
||||
|
||||
// MOVW R4, panic_argp(R1)
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AMOVW
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R4
|
||||
@ -487,7 +487,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.To.Offset = 0 // Panic.argp
|
||||
|
||||
// B end
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AB
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
p.Pcond = end
|
||||
@ -527,7 +527,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
// with the same stackframe, so no spadj.
|
||||
if p.To.Sym != nil { // retjmp
|
||||
p.To.Reg = REGLINK
|
||||
q2 = obj.Appendp(ctxt, p)
|
||||
q2 = obj.Appendp(p, newprog)
|
||||
q2.As = AB
|
||||
q2.To.Type = obj.TYPE_BRANCH
|
||||
q2.To.Sym = p.To.Sym
|
||||
@ -576,7 +576,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.To.Reg = REGTMP
|
||||
|
||||
/* MOV a,m_divmod(REGTMP) */
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AMOVW
|
||||
p.Pos = q1.Pos
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -586,7 +586,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.To.Offset = 8 * 4 // offset of m.divmod
|
||||
|
||||
/* MOV b, R8 */
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AMOVW
|
||||
p.Pos = q1.Pos
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -599,7 +599,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.To.Offset = 0
|
||||
|
||||
/* CALL appropriate */
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ABL
|
||||
p.Pos = q1.Pos
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
@ -618,7 +618,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
|
||||
/* MOV REGTMP, b */
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AMOVW
|
||||
p.Pos = q1.Pos
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -645,7 +645,7 @@ func isfloatreg(a *obj.Addr) bool {
|
||||
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 {
|
||||
return
|
||||
}
|
||||
@ -699,7 +699,7 @@ func softfloat(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
|
||||
soft:
|
||||
if wasfloat == 0 || (p.Mark&LABEL != 0) {
|
||||
next = ctxt.NewProg()
|
||||
next = newprog()
|
||||
*next = *p
|
||||
|
||||
// BL _sfloat(SB)
|
||||
@ -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
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = AMOVW
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
@ -739,7 +739,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
if framesize <= obj.StackSmall {
|
||||
// small stack: SP < stackguard
|
||||
// CMP stackguard, SP
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = ACMP
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -749,7 +749,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
// large stack: SP-framesize < stackguard-StackSmall
|
||||
// MOVW $-(framesize-StackSmall)(SP), R2
|
||||
// CMP stackguard, R2
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = AMOVW
|
||||
p.From.Type = obj.TYPE_ADDR
|
||||
@ -758,7 +758,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R2
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ACMP
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R1
|
||||
@ -774,14 +774,14 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
// SUB.NE R1, R2
|
||||
// MOVW.NE $(framesize+(StackGuard-StackSmall)), R3
|
||||
// CMP.NE R3, R2
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = ACMP
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1)))
|
||||
p.Reg = REG_R1
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AMOVW
|
||||
p.From.Type = obj.TYPE_ADDR
|
||||
p.From.Reg = REGSP
|
||||
@ -790,7 +790,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.To.Reg = REG_R2
|
||||
p.Scond = C_SCOND_NE
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ASUB
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R1
|
||||
@ -798,7 +798,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.To.Reg = REG_R2
|
||||
p.Scond = C_SCOND_NE
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AMOVW
|
||||
p.From.Type = obj.TYPE_ADDR
|
||||
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 {
|
||||
p.To.Reg = REG_R3
|
||||
p.Scond = C_SCOND_NE
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ACMP
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R3
|
||||
@ -815,7 +815,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
}
|
||||
|
||||
// BLS call-to-morestack
|
||||
bls := obj.Appendp(ctxt, p)
|
||||
bls := obj.Appendp(p, newprog)
|
||||
bls.As = ABLS
|
||||
bls.To.Type = obj.TYPE_BRANCH
|
||||
|
||||
@ -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
|
||||
// we are still in function prologue. We need to fix the
|
||||
// SP data and PCDATA.
|
||||
spfix := obj.Appendp(ctxt, last)
|
||||
spfix := obj.Appendp(last, newprog)
|
||||
spfix.As = obj.ANOP
|
||||
spfix.Spadj = -framesize
|
||||
|
||||
pcdata := obj.Appendp(ctxt, spfix)
|
||||
pcdata := obj.Appendp(spfix, newprog)
|
||||
pcdata.Pos = ctxt.Cursym.Text.Pos
|
||||
pcdata.As = obj.APCDATA
|
||||
pcdata.From.Type = obj.TYPE_CONST
|
||||
@ -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
|
||||
|
||||
// MOVW LR, R3
|
||||
movw := obj.Appendp(ctxt, pcdata)
|
||||
movw := obj.Appendp(pcdata, newprog)
|
||||
movw.As = AMOVW
|
||||
movw.From.Type = obj.TYPE_REG
|
||||
movw.From.Reg = REGLINK
|
||||
@ -849,7 +849,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
bls.Pcond = movw
|
||||
|
||||
// BL runtime.morestack
|
||||
call := obj.Appendp(ctxt, movw)
|
||||
call := obj.Appendp(movw, newprog)
|
||||
call.As = obj.ACALL
|
||||
call.To.Type = obj.TYPE_BRANCH
|
||||
morestack := "runtime.morestack"
|
||||
@ -862,7 +862,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
call.To.Sym = obj.Linklookup(ctxt, morestack, 0)
|
||||
|
||||
// B start
|
||||
b := obj.Appendp(ctxt, call)
|
||||
b := obj.Appendp(call, newprog)
|
||||
b.As = obj.AJMP
|
||||
b.To.Type = obj.TYPE_BRANCH
|
||||
b.Pcond = ctxt.Cursym.Text.Link
|
||||
|
@ -524,7 +524,7 @@ var pool struct {
|
||||
size uint32
|
||||
}
|
||||
|
||||
func span7(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
p := cursym.Text
|
||||
if p == nil || p.Link == nil { // handle external functions and ELF section symbols
|
||||
return
|
||||
@ -557,19 +557,19 @@ func span7(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
|
||||
switch o.flag & (LFROM | LTO) {
|
||||
case LFROM:
|
||||
addpool(ctxt, p, &p.From)
|
||||
addpool(ctxt, newprog, p, &p.From)
|
||||
|
||||
case LTO:
|
||||
addpool(ctxt, p, &p.To)
|
||||
addpool(ctxt, newprog, p, &p.To)
|
||||
break
|
||||
}
|
||||
|
||||
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)
|
||||
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) {
|
||||
if (o.type_ == 7 || o.type_ == 39) && p.Pcond != nil { // 7: BEQ and like, 39: CBZ and like
|
||||
otxt := p.Pcond.Pc - c
|
||||
if otxt <= -(1<<18)+10 || otxt >= (1<<18)-10 {
|
||||
q := ctxt.NewProg()
|
||||
q := newprog()
|
||||
q.Link = p.Link
|
||||
p.Link = q
|
||||
q.As = AB
|
||||
q.To.Type = obj.TYPE_BRANCH
|
||||
q.Pcond = p.Pcond
|
||||
p.Pcond = q
|
||||
q = ctxt.NewProg()
|
||||
q = newprog()
|
||||
q.Link = p.Link
|
||||
p.Link = q
|
||||
q.As = AB
|
||||
@ -670,21 +670,21 @@ func span7(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
* to go out of range of a 1Mb PC-relative offset
|
||||
* 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)) {
|
||||
flushpool(ctxt, p, skip)
|
||||
flushpool(ctxt, newprog, p, skip)
|
||||
} 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 skip != 0 {
|
||||
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)
|
||||
}
|
||||
q := ctxt.NewProg()
|
||||
q := newprog()
|
||||
q.As = AB
|
||||
q.To.Type = obj.TYPE_BRANCH
|
||||
q.Pcond = p.Link
|
||||
@ -715,10 +715,10 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int) {
|
||||
/*
|
||||
* 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)
|
||||
lit := ctxt.Instoffset
|
||||
t := *ctxt.NewProg()
|
||||
t := *newprog()
|
||||
t.As = AWORD
|
||||
sz := 4
|
||||
|
||||
@ -789,7 +789,7 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
|
||||
}
|
||||
}
|
||||
|
||||
q := ctxt.NewProg()
|
||||
q := newprog()
|
||||
*q = t
|
||||
q.Pc = int64(pool.size)
|
||||
if ctxt.Blitrl == nil {
|
||||
|
@ -48,9 +48,9 @@ var complements = []obj.As{
|
||||
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
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
@ -67,7 +67,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
// small stack: SP < stackguard
|
||||
// MOV SP, R2
|
||||
// CMP stackguard, R2
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -75,7 +75,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R2
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ACMP
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R1
|
||||
@ -84,7 +84,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
// large stack: SP-framesize < stackguard-StackSmall
|
||||
// SUB $(framesize-StackSmall), SP, R2
|
||||
// CMP stackguard, R2
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = ASUB
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
@ -93,7 +93,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R2
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ACMP
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R1
|
||||
@ -110,19 +110,19 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
// SUB R1, R2
|
||||
// MOV $(framesize+(StackGuard-StackSmall)), R3
|
||||
// CMP R3, R2
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = ACMP
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = obj.StackPreempt
|
||||
p.Reg = REG_R1
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
q = p
|
||||
p.As = ABEQ
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AADD
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = obj.StackGuard
|
||||
@ -130,21 +130,21 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R2
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ASUB
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R1
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R2
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall)
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R3
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ACMP
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R3
|
||||
@ -152,7 +152,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
}
|
||||
|
||||
// BLS do-morestack
|
||||
bls := obj.Appendp(ctxt, p)
|
||||
bls := obj.Appendp(p, newprog)
|
||||
bls.As = ABLS
|
||||
bls.To.Type = obj.TYPE_BRANCH
|
||||
|
||||
@ -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
|
||||
// we are still in function prologue. We need to fix the
|
||||
// SP data and PCDATA.
|
||||
spfix := obj.Appendp(ctxt, last)
|
||||
spfix := obj.Appendp(last, newprog)
|
||||
spfix.As = obj.ANOP
|
||||
spfix.Spadj = -framesize
|
||||
|
||||
pcdata := obj.Appendp(ctxt, spfix)
|
||||
pcdata := obj.Appendp(spfix, newprog)
|
||||
pcdata.Pos = ctxt.Cursym.Text.Pos
|
||||
pcdata.As = obj.APCDATA
|
||||
pcdata.From.Type = obj.TYPE_CONST
|
||||
@ -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
|
||||
|
||||
// MOV LR, R3
|
||||
movlr := obj.Appendp(ctxt, pcdata)
|
||||
movlr := obj.Appendp(pcdata, newprog)
|
||||
movlr.As = AMOVD
|
||||
movlr.From.Type = obj.TYPE_REG
|
||||
movlr.From.Reg = REGLINK
|
||||
@ -189,7 +189,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
|
||||
debug := movlr
|
||||
if false {
|
||||
debug = obj.Appendp(ctxt, debug)
|
||||
debug = obj.Appendp(debug, newprog)
|
||||
debug.As = AMOVD
|
||||
debug.From.Type = obj.TYPE_CONST
|
||||
debug.From.Offset = int64(framesize)
|
||||
@ -198,7 +198,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
}
|
||||
|
||||
// BL runtime.morestack(SB)
|
||||
call := obj.Appendp(ctxt, debug)
|
||||
call := obj.Appendp(debug, newprog)
|
||||
call.As = ABL
|
||||
call.To.Type = obj.TYPE_BRANCH
|
||||
morestack := "runtime.morestack"
|
||||
@ -211,7 +211,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
call.To.Sym = obj.Linklookup(ctxt, morestack, 0)
|
||||
|
||||
// B start
|
||||
jmp := obj.Appendp(ctxt, call)
|
||||
jmp := obj.Appendp(call, newprog)
|
||||
jmp.As = AB
|
||||
jmp.To.Type = obj.TYPE_BRANCH
|
||||
jmp.Pcond = ctxt.Cursym.Text.Link
|
||||
@ -224,7 +224,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
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.To.Class = 0
|
||||
|
||||
@ -326,12 +326,12 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||
}
|
||||
|
||||
if ctxt.Flag_dynlink {
|
||||
rewriteToUseGot(ctxt, p)
|
||||
rewriteToUseGot(ctxt, p, newprog)
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// ADUFFxxx $offset
|
||||
// becomes
|
||||
@ -354,13 +354,13 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
p.To.Name = obj.NAME_NONE
|
||||
p.To.Offset = 0
|
||||
p.To.Sym = nil
|
||||
p1 := obj.Appendp(ctxt, p)
|
||||
p1 := obj.Appendp(p, newprog)
|
||||
p1.As = AADD
|
||||
p1.From.Type = obj.TYPE_CONST
|
||||
p1.From.Offset = offset
|
||||
p1.To.Type = obj.TYPE_REG
|
||||
p1.To.Reg = REGTMP
|
||||
p2 := obj.Appendp(ctxt, p1)
|
||||
p2 := obj.Appendp(p1, newprog)
|
||||
p2.As = obj.ACALL
|
||||
p2.To.Type = obj.TYPE_REG
|
||||
p2.To.Reg = REGTMP
|
||||
@ -381,7 +381,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Name = obj.NAME_GOTREF
|
||||
if p.From.Offset != 0 {
|
||||
q := obj.Appendp(ctxt, p)
|
||||
q := obj.Appendp(p, newprog)
|
||||
q.As = AADD
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = p.From.Offset
|
||||
@ -415,8 +415,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
if source.Type != obj.TYPE_MEM {
|
||||
ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
||||
}
|
||||
p1 := obj.Appendp(ctxt, p)
|
||||
p2 := obj.Appendp(ctxt, p1)
|
||||
p1 := obj.Appendp(p, newprog)
|
||||
p2 := obj.Appendp(p1, newprog)
|
||||
p1.As = AMOVD
|
||||
p1.From.Type = obj.TYPE_MEM
|
||||
p1.From.Sym = source.Sym
|
||||
@ -441,7 +441,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
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
|
||||
|
||||
if cursym.Text == nil || cursym.Text.Link == nil {
|
||||
@ -561,7 +561,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
|
||||
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
|
||||
@ -583,7 +583,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
// Store link register before decrementing SP, so if a signal comes
|
||||
// during the execution of the function prologue, the traceback
|
||||
// code will not see a half-updated stack frame.
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.Pos = p.Pos
|
||||
q.As = ASUB
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
@ -592,7 +592,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REGTMP
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.Pos = p.Pos
|
||||
q.As = AMOVD
|
||||
q.From.Type = obj.TYPE_REG
|
||||
@ -600,7 +600,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_MEM
|
||||
q.To.Reg = REGTMP
|
||||
|
||||
q1 = obj.Appendp(ctxt, q)
|
||||
q1 = obj.Appendp(q, newprog)
|
||||
q1.Pos = p.Pos
|
||||
q1.As = AMOVD
|
||||
q1.From.Type = obj.TYPE_REG
|
||||
@ -610,7 +610,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q1.Spadj = ctxt.Autosize
|
||||
} else {
|
||||
// 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.Pos = p.Pos
|
||||
q1.From.Type = obj.TYPE_REG
|
||||
@ -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.
|
||||
q = q1
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AMOVD
|
||||
q.From.Type = obj.TYPE_MEM
|
||||
q.From.Reg = REGG
|
||||
@ -649,18 +649,18 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R1
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = ACMP
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REGZERO
|
||||
q.Reg = REG_R1
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = ABEQ
|
||||
q.To.Type = obj.TYPE_BRANCH
|
||||
q1 = q
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AMOVD
|
||||
q.From.Type = obj.TYPE_MEM
|
||||
q.From.Reg = REG_R1
|
||||
@ -668,7 +668,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R2
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AADD
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = int64(ctxt.Autosize) + 8
|
||||
@ -676,18 +676,18 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R3
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = ACMP
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REG_R2
|
||||
q.Reg = REG_R3
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = ABNE
|
||||
q.To.Type = obj.TYPE_BRANCH
|
||||
q2 = q
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AADD
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = 8
|
||||
@ -695,7 +695,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R4
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AMOVD
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REG_R4
|
||||
@ -703,7 +703,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Reg = REG_R1
|
||||
q.To.Offset = 0 // Panic.argp
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
|
||||
q.As = obj.ANOP
|
||||
q1.Pcond = q
|
||||
@ -744,7 +744,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.To.Reg = REGLINK
|
||||
p.Spadj = -aoffset
|
||||
if ctxt.Autosize > aoffset {
|
||||
q = ctxt.NewProg()
|
||||
q = newprog()
|
||||
q.As = AADD
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = int64(ctxt.Autosize) - int64(aoffset)
|
||||
@ -759,7 +759,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
|
||||
if p.As != obj.ARET {
|
||||
q = ctxt.NewProg()
|
||||
q = newprog()
|
||||
q.Pos = p.Pos
|
||||
q.Link = p.Link
|
||||
p.Link = q
|
||||
|
@ -76,8 +76,8 @@ func mkfwd(sym *LSym) {
|
||||
}
|
||||
}
|
||||
|
||||
func Appendp(ctxt *Link, q *Prog) *Prog {
|
||||
p := ctxt.NewProg()
|
||||
func Appendp(q *Prog, newprog ProgAlloc) *Prog {
|
||||
p := newprog()
|
||||
p.Link = q.Link
|
||||
q.Link = p
|
||||
p.Pos = q.Pos
|
||||
|
@ -224,7 +224,8 @@ const (
|
||||
// Each Prog is charged to a specific source line in the debug information,
|
||||
// specified by Pos.Line().
|
||||
// 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
|
||||
// be left zeroed by creators of Prog lists.
|
||||
@ -789,9 +790,9 @@ type SymVer struct {
|
||||
// LinkArch is the definition of a single architecture.
|
||||
type LinkArch struct {
|
||||
*sys.Arch
|
||||
Preprocess func(*Link, *LSym)
|
||||
Assemble func(*Link, *LSym)
|
||||
Progedit func(*Link, *Prog)
|
||||
Preprocess func(*Link, *LSym, ProgAlloc)
|
||||
Assemble func(*Link, *LSym, ProgAlloc)
|
||||
Progedit func(*Link, *Prog, ProgAlloc)
|
||||
UnaryDst map[As]bool // Instruction takes one operand, a destination.
|
||||
}
|
||||
|
||||
|
@ -373,7 +373,7 @@ var oprange [ALAST & obj.AMask][]Optab
|
||||
|
||||
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
|
||||
if p == nil || p.Link == nil { // handle external functions and ELF section symbols
|
||||
return
|
||||
@ -430,7 +430,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
if o.type_ == 6 && p.Pcond != nil {
|
||||
otxt = p.Pcond.Pc - c
|
||||
if otxt < -(1<<17)+10 || otxt >= (1<<17)-10 {
|
||||
q = ctxt.NewProg()
|
||||
q = newprog()
|
||||
q.Link = p.Link
|
||||
p.Link = q
|
||||
q.As = AJMP
|
||||
@ -438,7 +438,7 @@ func span0(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_BRANCH
|
||||
q.Pcond = p.Pcond
|
||||
p.Pcond = q
|
||||
q = ctxt.NewProg()
|
||||
q = newprog()
|
||||
q.Link = p.Link
|
||||
p.Link = q
|
||||
q.As = AJMP
|
||||
@ -446,8 +446,8 @@ func span0(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_BRANCH
|
||||
q.Pcond = q.Link.Link
|
||||
|
||||
addnop(ctxt, p.Link)
|
||||
addnop(ctxt, p)
|
||||
addnop(ctxt, p.Link, newprog)
|
||||
addnop(ctxt, p, newprog)
|
||||
bflag = 1
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ import (
|
||||
"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.To.Class = 0
|
||||
|
||||
@ -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.
|
||||
ctxt.Cursym = cursym
|
||||
|
||||
@ -298,7 +298,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.To.Offset = int64(autosize) - ctxt.FixedFrameSize()
|
||||
|
||||
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
|
||||
@ -309,7 +309,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
// Store link register before decrement SP, so if a signal comes
|
||||
// during the execution of the function prologue, the traceback
|
||||
// code will not see a half-updated stack frame.
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = mov
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_REG
|
||||
@ -318,7 +318,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Offset = int64(-autosize)
|
||||
q.To.Reg = REGSP
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = add
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
@ -357,7 +357,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
// 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.
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
|
||||
q.As = mov
|
||||
q.From.Type = obj.TYPE_MEM
|
||||
@ -366,7 +366,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R1
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = ABEQ
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REG_R1
|
||||
@ -374,7 +374,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.Mark |= BRANCH
|
||||
p1 = q
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = mov
|
||||
q.From.Type = obj.TYPE_MEM
|
||||
q.From.Reg = REG_R1
|
||||
@ -382,7 +382,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R2
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = add
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = int64(autosize) + ctxt.FixedFrameSize()
|
||||
@ -390,7 +390,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R3
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = ABNE
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REG_R2
|
||||
@ -399,7 +399,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.Mark |= BRANCH
|
||||
p2 = q
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = add
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = ctxt.FixedFrameSize()
|
||||
@ -407,7 +407,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R2
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = mov
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REG_R2
|
||||
@ -415,7 +415,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Reg = REG_R1
|
||||
q.To.Offset = 0 // Panic.argp
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
|
||||
q.As = obj.ANOP
|
||||
p1.Pcond = q
|
||||
@ -456,7 +456,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.To.Reg = REGSP
|
||||
p.Spadj = -autosize
|
||||
|
||||
q = ctxt.NewProg()
|
||||
q = newprog()
|
||||
q.As = AJMP
|
||||
q.Pos = p.Pos
|
||||
q.To.Type = obj.TYPE_MEM
|
||||
@ -481,7 +481,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
|
||||
if autosize != 0 {
|
||||
q = ctxt.NewProg()
|
||||
q = newprog()
|
||||
q.As = add
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
@ -494,7 +494,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.Link = q
|
||||
}
|
||||
|
||||
q1 = ctxt.NewProg()
|
||||
q1 = newprog()
|
||||
q1.As = AJMP
|
||||
q1.Pos = p.Pos
|
||||
if retSym != nil { // retjmp
|
||||
@ -535,7 +535,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
|
||||
p.As = AMOVF
|
||||
q = ctxt.NewProg()
|
||||
q = newprog()
|
||||
*q = *p
|
||||
q.Link = p.Link
|
||||
p.Link = q
|
||||
@ -564,7 +564,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
// NOP after each branch instruction.
|
||||
for p = cursym.Text; p != nil; p = p.Link {
|
||||
if p.Mark&BRANCH != 0 {
|
||||
addnop(ctxt, p)
|
||||
addnop(ctxt, p, newprog)
|
||||
}
|
||||
}
|
||||
return
|
||||
@ -579,7 +579,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
o++
|
||||
if p.Mark&NOSCHED != 0 {
|
||||
if q1 != p {
|
||||
sched(ctxt, q1, q)
|
||||
sched(ctxt, newprog, q1, q)
|
||||
}
|
||||
for ; p != nil; p = p.Link {
|
||||
if p.Mark&NOSCHED == 0 {
|
||||
@ -594,18 +594,18 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
if p.Mark&(LABEL|SYNC) != 0 {
|
||||
if q1 != p {
|
||||
sched(ctxt, q1, q)
|
||||
sched(ctxt, newprog, q1, q)
|
||||
}
|
||||
q1 = p
|
||||
o = 1
|
||||
}
|
||||
if p.Mark&(BRANCH|SYNC) != 0 {
|
||||
sched(ctxt, q1, p)
|
||||
sched(ctxt, newprog, q1, p)
|
||||
q1 = p1
|
||||
o = 0
|
||||
}
|
||||
if o >= NSCHED {
|
||||
sched(ctxt, q1, p)
|
||||
sched(ctxt, newprog, q1, p)
|
||||
q1 = p1
|
||||
o = 0
|
||||
}
|
||||
@ -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.
|
||||
if framesize == 0 {
|
||||
return p
|
||||
@ -632,7 +632,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
}
|
||||
|
||||
// MOV g_stackguard(g), R1
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = mov
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
@ -648,7 +648,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
if framesize <= obj.StackSmall {
|
||||
// small stack: SP < stackguard
|
||||
// AGTU SP, stackguard, R1
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = ASGTU
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -660,7 +660,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
// large stack: SP-framesize < stackguard-StackSmall
|
||||
// ADD $-(framesize-StackSmall), SP, R2
|
||||
// SGTU R2, stackguard, R1
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = add
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
@ -669,7 +669,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R2
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ASGTU
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R2
|
||||
@ -692,7 +692,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
// SUB R1, R2
|
||||
// MOV $(framesize+(StackGuard-StackSmall)), R1
|
||||
// SGTU R2, R1, R1
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = mov
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
@ -700,7 +700,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R2
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
q = p
|
||||
p.As = ABEQ
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -709,7 +709,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
p.Mark |= BRANCH
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = add
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = obj.StackGuard
|
||||
@ -717,21 +717,21 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R2
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = sub
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R1
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R2
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = mov
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R1
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ASGTU
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R2
|
||||
@ -741,7 +741,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
}
|
||||
|
||||
// q1: BNE R1, done
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
q1 := p
|
||||
|
||||
p.As = ABNE
|
||||
@ -751,7 +751,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.Mark |= BRANCH
|
||||
|
||||
// MOV LINK, R3
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = mov
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -764,7 +764,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
}
|
||||
|
||||
// JAL runtime.morestack(SB)
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = AJAL
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
@ -778,7 +778,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.Mark |= BRANCH
|
||||
|
||||
// JMP start
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = AJMP
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
@ -786,7 +786,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.Mark |= BRANCH
|
||||
|
||||
// placeholder for q1's jump target
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = obj.ANOP // zero-width place holder
|
||||
q1.Pcond = p
|
||||
@ -794,8 +794,8 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
return p
|
||||
}
|
||||
|
||||
func addnop(ctxt *obj.Link, p *obj.Prog) {
|
||||
q := ctxt.NewProg()
|
||||
func addnop(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
||||
q := newprog()
|
||||
// we want to use the canonical NOP (SLL $0,R0,R0) here,
|
||||
// however, as the assembler will always replace $0
|
||||
// as R0, we have to resort to manually encode the SLL
|
||||
@ -838,7 +838,7 @@ type Sch struct {
|
||||
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
|
||||
|
||||
/*
|
||||
@ -923,7 +923,7 @@ func sched(ctxt *obj.Link, p0, pe *obj.Prog) {
|
||||
}
|
||||
for s[0].nop != 0 {
|
||||
s[0].nop--
|
||||
addnop(ctxt, p)
|
||||
addnop(ctxt, p, newprog)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ func checkaddr(ctxt *Link, p *Prog, a *Addr) {
|
||||
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 name string
|
||||
var q *Prog
|
||||
@ -130,7 +130,7 @@ func linkpatch(ctxt *Link, sym *LSym) {
|
||||
checkaddr(ctxt, p, &p.To)
|
||||
|
||||
if ctxt.Arch.Progedit != nil {
|
||||
ctxt.Arch.Progedit(ctxt, p)
|
||||
ctxt.Arch.Progedit(ctxt, p, newprog)
|
||||
}
|
||||
if p.To.Type != TYPE_BRANCH {
|
||||
continue
|
||||
|
@ -15,6 +15,10 @@ type Plist struct {
|
||||
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) {
|
||||
flushplist(ctxt, plist, !ctxt.Debugasm)
|
||||
}
|
||||
@ -97,6 +101,8 @@ func flushplist(ctxt *Link, plist *Plist, freeProgs bool) {
|
||||
etext = p
|
||||
}
|
||||
|
||||
newprog := ProgAlloc(ctxt.NewProg)
|
||||
|
||||
// Add reference to Go arguments for C or assembly functions without them.
|
||||
for _, s := range text {
|
||||
if !strings.HasPrefix(s.Name, "\"\".") {
|
||||
@ -111,7 +117,7 @@ func flushplist(ctxt *Link, plist *Plist, freeProgs bool) {
|
||||
}
|
||||
|
||||
if !found {
|
||||
p := Appendp(ctxt, s.Text)
|
||||
p := Appendp(s.Text, newprog)
|
||||
p.As = AFUNCDATA
|
||||
p.From.Type = TYPE_CONST
|
||||
p.From.Offset = FUNCDATA_ArgsPointerMaps
|
||||
@ -124,9 +130,9 @@ func flushplist(ctxt *Link, plist *Plist, freeProgs bool) {
|
||||
// Turn functions into machine code images.
|
||||
for _, s := range text {
|
||||
mkfwd(s)
|
||||
linkpatch(ctxt, s)
|
||||
ctxt.Arch.Preprocess(ctxt, s)
|
||||
ctxt.Arch.Assemble(ctxt, s)
|
||||
linkpatch(ctxt, s, newprog)
|
||||
ctxt.Arch.Preprocess(ctxt, s, newprog)
|
||||
ctxt.Arch.Assemble(ctxt, s, newprog)
|
||||
linkpcln(ctxt, s)
|
||||
makeFuncDebugEntry(ctxt, plist.Curfn, s)
|
||||
if freeProgs {
|
||||
|
@ -552,7 +552,7 @@ var oprange [ALAST & obj.AMask][]Optab
|
||||
|
||||
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
|
||||
if p == nil || p.Link == nil { // handle external functions and ELF section symbols
|
||||
return
|
||||
@ -609,14 +609,14 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil {
|
||||
otxt = p.Pcond.Pc - c
|
||||
if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
|
||||
q = ctxt.NewProg()
|
||||
q = newprog()
|
||||
q.Link = p.Link
|
||||
p.Link = q
|
||||
q.As = ABR
|
||||
q.To.Type = obj.TYPE_BRANCH
|
||||
q.Pcond = p.Pcond
|
||||
p.Pcond = q
|
||||
q = ctxt.NewProg()
|
||||
q = newprog()
|
||||
q.Link = p.Link
|
||||
p.Link = q
|
||||
q.As = ABR
|
||||
|
@ -36,7 +36,7 @@ import (
|
||||
"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.To.Class = 0
|
||||
|
||||
@ -116,12 +116,12 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||
}
|
||||
}
|
||||
if ctxt.Flag_dynlink {
|
||||
rewriteToUseGot(ctxt, p)
|
||||
rewriteToUseGot(ctxt, p, newprog)
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// ADUFFxxx $offset
|
||||
// becomes
|
||||
@ -145,19 +145,19 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
p.To.Name = obj.NAME_NONE
|
||||
p.To.Offset = 0
|
||||
p.To.Sym = nil
|
||||
p1 := obj.Appendp(ctxt, p)
|
||||
p1 := obj.Appendp(p, newprog)
|
||||
p1.As = AADD
|
||||
p1.From.Type = obj.TYPE_CONST
|
||||
p1.From.Offset = offset
|
||||
p1.To.Type = obj.TYPE_REG
|
||||
p1.To.Reg = REG_R12
|
||||
p2 := obj.Appendp(ctxt, p1)
|
||||
p2 := obj.Appendp(p1, newprog)
|
||||
p2.As = AMOVD
|
||||
p2.From.Type = obj.TYPE_REG
|
||||
p2.From.Reg = REG_R12
|
||||
p2.To.Type = obj.TYPE_REG
|
||||
p2.To.Reg = REG_CTR
|
||||
p3 := obj.Appendp(ctxt, p2)
|
||||
p3 := obj.Appendp(p2, newprog)
|
||||
p3.As = obj.ACALL
|
||||
p3.From.Type = obj.TYPE_REG
|
||||
p3.From.Reg = REG_R12
|
||||
@ -180,7 +180,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Name = obj.NAME_GOTREF
|
||||
if p.From.Offset != 0 {
|
||||
q := obj.Appendp(ctxt, p)
|
||||
q := obj.Appendp(p, newprog)
|
||||
q.As = AADD
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = p.From.Offset
|
||||
@ -214,8 +214,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
if source.Type != obj.TYPE_MEM {
|
||||
ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
||||
}
|
||||
p1 := obj.Appendp(ctxt, p)
|
||||
p2 := obj.Appendp(ctxt, p1)
|
||||
p1 := obj.Appendp(p, newprog)
|
||||
p2 := obj.Appendp(p1, newprog)
|
||||
|
||||
p1.As = AMOVD
|
||||
p1.From.Type = obj.TYPE_MEM
|
||||
@ -241,7 +241,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
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.
|
||||
ctxt.Cursym = cursym
|
||||
|
||||
@ -491,12 +491,12 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
// generate the addis instruction except as part of the
|
||||
// load of a large constant, and in that case there is no
|
||||
// way to use r12 as the source.
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AWORD
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = 0x3c4c0000
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AWORD
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
@ -509,7 +509,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -517,7 +517,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
// it is a leaf function, so that traceback works.
|
||||
if cursym.Text.Mark&LEAF == 0 && autosize >= -BIG && autosize <= BIG {
|
||||
// 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.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_REG
|
||||
@ -525,7 +525,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REGTMP
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AMOVDU
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_REG
|
||||
@ -539,7 +539,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
// Store link register before decrementing SP, so if a signal comes
|
||||
// during the execution of the function prologue, the traceback
|
||||
// code will not see a half-updated stack frame.
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AMOVD
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_REG
|
||||
@ -547,7 +547,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
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.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_REG
|
||||
@ -556,7 +556,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Offset = int64(-autosize)
|
||||
q.To.Reg = REGSP
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AADD
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
@ -578,7 +578,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
|
||||
if ctxt.Flag_shared {
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AMOVD
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_REG
|
||||
@ -606,7 +606,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
// 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.
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
|
||||
q.As = AMOVD
|
||||
q.From.Type = obj.TYPE_MEM
|
||||
@ -615,19 +615,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R3
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = ACMP
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REG_R0
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R3
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = ABEQ
|
||||
q.To.Type = obj.TYPE_BRANCH
|
||||
p1 = q
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AMOVD
|
||||
q.From.Type = obj.TYPE_MEM
|
||||
q.From.Reg = REG_R3
|
||||
@ -635,7 +635,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R4
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AADD
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = int64(autosize) + ctxt.FixedFrameSize()
|
||||
@ -643,19 +643,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R5
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = ACMP
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REG_R4
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R5
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = ABNE
|
||||
q.To.Type = obj.TYPE_BRANCH
|
||||
p2 = q
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AADD
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = ctxt.FixedFrameSize()
|
||||
@ -663,7 +663,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R6
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AMOVD
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REG_R6
|
||||
@ -671,7 +671,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Reg = REG_R3
|
||||
q.To.Offset = 0 // Panic.argp
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
|
||||
q.As = obj.ANOP
|
||||
p1.Pcond = q
|
||||
@ -708,7 +708,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.To.Reg = REGSP
|
||||
p.Spadj = -autosize
|
||||
|
||||
q = ctxt.NewProg()
|
||||
q = newprog()
|
||||
q.As = ABR
|
||||
q.Pos = p.Pos
|
||||
q.To.Type = obj.TYPE_REG
|
||||
@ -728,7 +728,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REGTMP
|
||||
|
||||
q = ctxt.NewProg()
|
||||
q = newprog()
|
||||
q.As = AMOVD
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_REG
|
||||
@ -742,7 +742,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
|
||||
if false {
|
||||
// Debug bad returns
|
||||
q = ctxt.NewProg()
|
||||
q = newprog()
|
||||
|
||||
q.As = AMOVD
|
||||
q.Pos = p.Pos
|
||||
@ -758,7 +758,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
|
||||
if autosize != 0 {
|
||||
q = ctxt.NewProg()
|
||||
q = newprog()
|
||||
q.As = AADD
|
||||
q.Pos = p.Pos
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
@ -771,7 +771,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.Link = q
|
||||
}
|
||||
|
||||
q1 = ctxt.NewProg()
|
||||
q1 = newprog()
|
||||
q1.As = ABR
|
||||
q1.Pos = p.Pos
|
||||
if retTarget == nil {
|
||||
@ -839,11 +839,11 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
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
|
||||
|
||||
// MOVD g_stackguard(g), R3
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
@ -859,7 +859,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
if framesize <= obj.StackSmall {
|
||||
// small stack: SP < stackguard
|
||||
// CMP stackguard, SP
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = ACMPU
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -870,7 +870,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
// large stack: SP-framesize < stackguard-StackSmall
|
||||
// ADD $-(framesize-StackSmall), SP, R4
|
||||
// CMP stackguard, R4
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = AADD
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
@ -879,7 +879,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R4
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ACMPU
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R3
|
||||
@ -901,7 +901,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
// SUB R3, R4
|
||||
// MOVD $(framesize+(StackGuard-StackSmall)), R31
|
||||
// CMPU R31, R4
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = ACMP
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -909,12 +909,12 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.To.Type = obj.TYPE_CONST
|
||||
p.To.Offset = obj.StackPreempt
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
q = p
|
||||
p.As = ABEQ
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AADD
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = obj.StackGuard
|
||||
@ -922,21 +922,21 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R4
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ASUB
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R3
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R4
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REGTMP
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ACMPU
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REGTMP
|
||||
@ -945,14 +945,14 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
}
|
||||
|
||||
// q1: BLT done
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
q1 := p
|
||||
|
||||
p.As = ABLT
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
|
||||
// MOVD LR, R5
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -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.
|
||||
|
||||
// MOVD R12, 8(SP)
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R2
|
||||
@ -1006,7 +1006,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
// seems preferable.
|
||||
|
||||
// MOVD $runtime.morestack(SB), R12
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Sym = morestacksym
|
||||
@ -1015,7 +1015,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.To.Reg = REG_R12
|
||||
|
||||
// MOVD R12, CTR
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R12
|
||||
@ -1023,7 +1023,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.To.Reg = REG_CTR
|
||||
|
||||
// BL CTR
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = obj.ACALL
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R12
|
||||
@ -1031,7 +1031,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
p.To.Reg = REG_CTR
|
||||
} else {
|
||||
// BL runtime.morestack(SB)
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = ABL
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
@ -1040,7 +1040,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
|
||||
if ctxt.Flag_shared {
|
||||
// MOVD 8(SP), R2
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Reg = REGSP
|
||||
@ -1050,13 +1050,13 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
|
||||
}
|
||||
|
||||
// BR start
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ABR
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
p.Pcond = p0.Link
|
||||
|
||||
// placeholder for q1's jump target
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = obj.ANOP // zero-width place holder
|
||||
q1.Pcond = p
|
||||
|
@ -385,7 +385,7 @@ var oprange [ALAST & obj.AMask][]Optab
|
||||
|
||||
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
|
||||
if p == nil || p.Link == nil { // handle external functions and ELF section symbols
|
||||
return
|
||||
|
@ -36,7 +36,7 @@ import (
|
||||
"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.To.Class = 0
|
||||
|
||||
@ -122,12 +122,12 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||
}
|
||||
|
||||
if ctxt.Flag_dynlink {
|
||||
rewriteToUseGot(ctxt, p)
|
||||
rewriteToUseGot(ctxt, p, newprog)
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
// assembly code.
|
||||
if p.As == AEXRL {
|
||||
@ -147,7 +147,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
p.From.Name = obj.NAME_GOTREF
|
||||
q := p
|
||||
if p.From.Offset != 0 {
|
||||
q = obj.Appendp(ctxt, p)
|
||||
q = obj.Appendp(p, newprog)
|
||||
q.As = AADD
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = p.From.Offset
|
||||
@ -181,8 +181,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
if source.Type != obj.TYPE_MEM {
|
||||
ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
||||
}
|
||||
p1 := obj.Appendp(ctxt, p)
|
||||
p2 := obj.Appendp(ctxt, p1)
|
||||
p1 := obj.Appendp(p, newprog)
|
||||
p2 := obj.Appendp(p1, newprog)
|
||||
|
||||
p1.As = AMOVD
|
||||
p1.From.Type = obj.TYPE_MEM
|
||||
@ -208,7 +208,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
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.
|
||||
ctxt.Cursym = cursym
|
||||
|
||||
@ -332,7 +332,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q := p
|
||||
|
||||
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
|
||||
wasSplit = true //need post part of split
|
||||
}
|
||||
@ -343,7 +343,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
// Store link register before decrementing SP, so if a signal comes
|
||||
// during the execution of the function prologue, the traceback
|
||||
// code will not see a half-updated stack frame.
|
||||
q = obj.Appendp(ctxt, p)
|
||||
q = obj.Appendp(p, newprog)
|
||||
q.As = AMOVD
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REG_LR
|
||||
@ -351,7 +351,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Reg = REGSP
|
||||
q.To.Offset = int64(-autosize)
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AMOVD
|
||||
q.From.Type = obj.TYPE_ADDR
|
||||
q.From.Offset = int64(-autosize)
|
||||
@ -389,7 +389,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
// 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.
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
|
||||
q.As = AMOVD
|
||||
q.From.Type = obj.TYPE_MEM
|
||||
@ -398,19 +398,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R3
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = ACMP
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REG_R3
|
||||
q.To.Type = obj.TYPE_CONST
|
||||
q.To.Offset = 0
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = ABEQ
|
||||
q.To.Type = obj.TYPE_BRANCH
|
||||
p1 := q
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AMOVD
|
||||
q.From.Type = obj.TYPE_MEM
|
||||
q.From.Reg = REG_R3
|
||||
@ -418,7 +418,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R4
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AADD
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = int64(autosize) + ctxt.FixedFrameSize()
|
||||
@ -426,19 +426,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R5
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = ACMP
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REG_R4
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R5
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = ABNE
|
||||
q.To.Type = obj.TYPE_BRANCH
|
||||
p2 := q
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AADD
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = ctxt.FixedFrameSize()
|
||||
@ -446,7 +446,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Type = obj.TYPE_REG
|
||||
q.To.Reg = REG_R6
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AMOVD
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REG_R6
|
||||
@ -454,7 +454,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.To.Reg = REG_R3
|
||||
q.To.Offset = 0 // Panic.argp
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
|
||||
q.As = obj.ANOP
|
||||
p1.Pcond = q
|
||||
@ -486,7 +486,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.To.Reg = REGSP
|
||||
p.Spadj = -autosize
|
||||
|
||||
q = obj.Appendp(ctxt, p)
|
||||
q = obj.Appendp(p, newprog)
|
||||
q.As = ABR
|
||||
q.From = obj.Addr{}
|
||||
q.To.Type = obj.TYPE_REG
|
||||
@ -506,7 +506,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q = p
|
||||
|
||||
if autosize != 0 {
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = AADD
|
||||
q.From.Type = obj.TYPE_CONST
|
||||
q.From.Offset = int64(autosize)
|
||||
@ -515,7 +515,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
q.Spadj = -autosize
|
||||
}
|
||||
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = ABR
|
||||
q.From = obj.Addr{}
|
||||
if retTarget == nil {
|
||||
@ -535,15 +535,15 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
}
|
||||
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
|
||||
|
||||
// MOVD g_stackguard(g), R3
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
@ -565,7 +565,7 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob
|
||||
|
||||
// q1: BLT done
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
//q1 = p
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R3
|
||||
@ -588,7 +588,7 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob
|
||||
// large stack: SP-framesize < stackguard-StackSmall
|
||||
// ADD $-(framesize-StackSmall), SP, R4
|
||||
// CMP stackguard, R4
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = AADD
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
@ -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.Reg = REG_R4
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R3
|
||||
p.Reg = REG_R4
|
||||
@ -620,7 +620,7 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob
|
||||
// SUB R3, R4
|
||||
// MOVD $(framesize+(StackGuard-StackSmall)), TEMP
|
||||
// CMPUBGE TEMP, R4
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = ACMP
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -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.Offset = obj.StackPreempt
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
q = p
|
||||
p.As = ABEQ
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AADD
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = obj.StackGuard
|
||||
@ -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.Reg = REG_R4
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ASUB
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_R3
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_R4
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REGTMP
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REGTMP
|
||||
p.Reg = REG_R4
|
||||
@ -666,15 +666,15 @@ func stacksplitPre(ctxt *obj.Link, p *obj.Prog, framesize int32) (*obj.Prog, *ob
|
||||
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
|
||||
// we are still in function prologue. We need to fix the
|
||||
// SP data and PCDATA.
|
||||
spfix := obj.Appendp(ctxt, p)
|
||||
spfix := obj.Appendp(p, newprog)
|
||||
spfix.As = obj.ANOP
|
||||
spfix.Spadj = -framesize
|
||||
|
||||
pcdata := obj.Appendp(ctxt, spfix)
|
||||
pcdata := obj.Appendp(spfix, newprog)
|
||||
pcdata.Pos = ctxt.Cursym.Text.Pos
|
||||
pcdata.As = obj.APCDATA
|
||||
pcdata.From.Type = obj.TYPE_CONST
|
||||
@ -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
|
||||
|
||||
// MOVD LR, R5
|
||||
p = obj.Appendp(ctxt, pcdata)
|
||||
p = obj.Appendp(pcdata, newprog)
|
||||
pPre.Pcond = p
|
||||
p.As = AMOVD
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -695,7 +695,7 @@ func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.P
|
||||
}
|
||||
|
||||
// BL runtime.morestack(SB)
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = ABL
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
@ -708,7 +708,7 @@ func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.P
|
||||
}
|
||||
|
||||
// BR start
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = ABR
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
|
@ -1762,7 +1762,7 @@ func spadjop(ctxt *obj.Link, p *obj.Prog, l, q obj.As) obj.As {
|
||||
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 {
|
||||
return
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ func CanUse1InsnTLS(ctxt *obj.Link) bool {
|
||||
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.
|
||||
// As a register, TLS refers to the thread-local storage base, and it
|
||||
// can only be loaded into another register:
|
||||
@ -146,7 +146,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||
// MOVQ TLS, 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 {
|
||||
q := obj.Appendp(ctxt, p)
|
||||
q := obj.Appendp(p, newprog)
|
||||
q.As = p.As
|
||||
q.From = p.From
|
||||
q.From.Type = obj.TYPE_MEM
|
||||
@ -293,16 +293,16 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
|
||||
}
|
||||
|
||||
if ctxt.Flag_dynlink {
|
||||
rewriteToUseGot(ctxt, p)
|
||||
rewriteToUseGot(ctxt, p, newprog)
|
||||
}
|
||||
|
||||
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.
|
||||
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 reg int16
|
||||
if ctxt.Arch.Family == sys.AMD64 {
|
||||
@ -345,13 +345,13 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
p.To.Reg = reg
|
||||
p.To.Offset = 0
|
||||
p.To.Sym = nil
|
||||
p1 := obj.Appendp(ctxt, p)
|
||||
p1 := obj.Appendp(p, newprog)
|
||||
p1.As = add
|
||||
p1.From.Type = obj.TYPE_CONST
|
||||
p1.From.Offset = offset
|
||||
p1.To.Type = obj.TYPE_REG
|
||||
p1.To.Reg = reg
|
||||
p2 := obj.Appendp(ctxt, p1)
|
||||
p2 := obj.Appendp(p1, newprog)
|
||||
p2.As = obj.ACALL
|
||||
p2.To.Type = obj.TYPE_REG
|
||||
p2.To.Reg = reg
|
||||
@ -388,7 +388,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
p.From.Name = obj.NAME_GOTREF
|
||||
q := p
|
||||
if p.From.Offset != 0 {
|
||||
q = obj.Appendp(ctxt, p)
|
||||
q = obj.Appendp(p, newprog)
|
||||
q.As = lea
|
||||
q.From.Type = obj.TYPE_MEM
|
||||
q.From.Reg = p.To.Reg
|
||||
@ -397,7 +397,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
p.From.Offset = 0
|
||||
}
|
||||
if cmplxdest {
|
||||
q = obj.Appendp(ctxt, q)
|
||||
q = obj.Appendp(q, newprog)
|
||||
q.As = pAs
|
||||
q.To = dest
|
||||
q.From.Type = obj.TYPE_REG
|
||||
@ -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 {
|
||||
return
|
||||
}
|
||||
p1 := obj.Appendp(ctxt, p)
|
||||
p2 := obj.Appendp(ctxt, p1)
|
||||
p1 := obj.Appendp(p, newprog)
|
||||
p2 := obj.Appendp(p1, newprog)
|
||||
|
||||
p1.As = ALEAL
|
||||
p1.From.Type = obj.TYPE_MEM
|
||||
@ -461,8 +461,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
if source.Type != obj.TYPE_MEM {
|
||||
ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
||||
}
|
||||
p1 := obj.Appendp(ctxt, p)
|
||||
p2 := obj.Appendp(ctxt, p1)
|
||||
p1 := obj.Appendp(p, newprog)
|
||||
p2 := obj.Appendp(p1, newprog)
|
||||
|
||||
p1.As = mov
|
||||
p1.From.Type = obj.TYPE_MEM
|
||||
@ -488,7 +488,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
|
||||
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
|
||||
// processed twice.
|
||||
if p.RegTo2 != 0 {
|
||||
@ -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"
|
||||
// respectively.
|
||||
if p.To.Type != obj.TYPE_REG {
|
||||
q := obj.Appendp(ctxt, p)
|
||||
q := obj.Appendp(p, newprog)
|
||||
q.As = p.As
|
||||
q.From.Type = obj.TYPE_REG
|
||||
q.From.Reg = REG_CX
|
||||
@ -537,9 +537,9 @@ func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog) {
|
||||
// Why? See the comment near the top of rewriteToUseGot above.
|
||||
// AMOVLs might be introduced by the GOT rewrites.
|
||||
}
|
||||
q := obj.Appendp(ctxt, p)
|
||||
q := obj.Appendp(p, newprog)
|
||||
q.RegTo2 = 1
|
||||
r := obj.Appendp(ctxt, q)
|
||||
r := obj.Appendp(q, newprog)
|
||||
r.RegTo2 = 1
|
||||
q.As = obj.ACALL
|
||||
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) {
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
ctxt.Plan9privates = obj.Linklookup(ctxt, "_privates", 0)
|
||||
}
|
||||
@ -676,19 +676,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
|
||||
if p.From3Offset()&obj.NOSPLIT == 0 || p.From3Offset()&obj.WRAPPER != 0 {
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = load_g_cx(ctxt, p) // load g into CX
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = load_g_cx(ctxt, p, newprog) // load g into CX
|
||||
}
|
||||
|
||||
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%int32(ctxt.Arch.RegSize) != 0 {
|
||||
ctxt.Diag("unaligned stack size %d", autoffset)
|
||||
}
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AADJSP
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = int64(autoffset)
|
||||
@ -699,7 +699,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
|
||||
if bpsize > 0 {
|
||||
// Save caller's BP
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = AMOVQ
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -710,7 +710,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.To.Offset = int64(autoffset) - int64(bpsize)
|
||||
|
||||
// Move current frame to BP
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = ALEAQ
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
@ -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.
|
||||
|
||||
// MOVQ g_panic(CX), BX
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AMOVQ
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Reg = REG_CX
|
||||
@ -765,7 +765,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
|
||||
// TESTQ BX, BX
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ATESTQ
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_BX
|
||||
@ -776,13 +776,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
|
||||
// JNE checkargp (checkargp to be resolved later)
|
||||
jne := obj.Appendp(ctxt, p)
|
||||
jne := obj.Appendp(p, newprog)
|
||||
jne.As = AJNE
|
||||
jne.To.Type = obj.TYPE_BRANCH
|
||||
|
||||
// end:
|
||||
// NOP
|
||||
end := obj.Appendp(ctxt, jne)
|
||||
end := obj.Appendp(jne, newprog)
|
||||
end.As = obj.ANOP
|
||||
|
||||
// Fast forward to end of function.
|
||||
@ -791,7 +791,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
|
||||
// LEAQ (autoffset+8)(SP), DI
|
||||
p = obj.Appendp(ctxt, last)
|
||||
p = obj.Appendp(last, newprog)
|
||||
p.As = ALEAQ
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Reg = REG_SP
|
||||
@ -806,7 +806,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
jne.Pcond = p
|
||||
|
||||
// CMPQ panic_argp(BX), DI
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ACMPQ
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Reg = REG_BX
|
||||
@ -825,13 +825,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
|
||||
// JNE end
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AJNE
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
p.Pcond = end
|
||||
|
||||
// MOVQ SP, panic_argp(BX)
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AMOVQ
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_SP
|
||||
@ -850,7 +850,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
}
|
||||
|
||||
// JMP end
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = obj.AJMP
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
p.Pcond = end
|
||||
@ -935,14 +935,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
|
||||
p.From.Offset = int64(autoffset) - int64(bpsize)
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_BP
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
}
|
||||
|
||||
p.As = AADJSP
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = int64(-autoffset)
|
||||
p.Spadj = -autoffset
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = obj.ARET
|
||||
|
||||
// If there are instructions following
|
||||
@ -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
|
||||
// prologue (caller must call appendp first) and in the epilogue.
|
||||
// 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
|
||||
if ctxt.Arch.PtrSize == 4 {
|
||||
p.As = AMOVL
|
||||
@ -999,7 +999,7 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
|
||||
p.To.Reg = REG_CX
|
||||
|
||||
next := p.Link
|
||||
progedit(ctxt, p)
|
||||
progedit(ctxt, p, newprog)
|
||||
for p.Link != next {
|
||||
p = p.Link
|
||||
}
|
||||
@ -1015,7 +1015,7 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog {
|
||||
// Appends to (does not overwrite) p.
|
||||
// Assumes g is in CX.
|
||||
// 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
|
||||
lea := ALEAQ
|
||||
mov := AMOVQ
|
||||
@ -1032,7 +1032,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32,
|
||||
if framesize <= obj.StackSmall {
|
||||
// small stack: SP <= stackguard
|
||||
// CMPQ SP, stackguard
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = cmp
|
||||
p.From.Type = obj.TYPE_REG
|
||||
@ -1046,7 +1046,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32,
|
||||
// large stack: SP-framesize <= stackguard-StackSmall
|
||||
// LEAQ -xxx(SP), AX
|
||||
// CMPQ AX, stackguard
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = lea
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
@ -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.Reg = REG_AX
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = cmp
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_AX
|
||||
@ -1080,7 +1080,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32,
|
||||
// SUBQ CX, AX
|
||||
// CMPQ AX, $(framesize+(StackGuard-StackSmall))
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
|
||||
p.As = mov
|
||||
indir_cx(ctxt, p, &p.From)
|
||||
@ -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.Reg = REG_SI
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = cmp
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_SI
|
||||
@ -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 = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AJEQ
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
q1 = p
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = lea
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Reg = REG_SP
|
||||
@ -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.Reg = REG_AX
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = sub
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_SI
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = REG_AX
|
||||
|
||||
p = obj.Appendp(ctxt, p)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = cmp
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_AX
|
||||
@ -1130,7 +1130,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, framesize int32,
|
||||
}
|
||||
|
||||
// common
|
||||
jls := obj.Appendp(ctxt, p)
|
||||
jls := obj.Appendp(p, newprog)
|
||||
jls.As = AJLS
|
||||
jls.To.Type = obj.TYPE_BRANCH
|
||||
|
||||
@ -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
|
||||
// we are still in function prologue. We need to fix the
|
||||
// SP data and PCDATA.
|
||||
spfix := obj.Appendp(ctxt, last)
|
||||
spfix := obj.Appendp(last, newprog)
|
||||
spfix.As = obj.ANOP
|
||||
spfix.Spadj = -framesize
|
||||
|
||||
pcdata := obj.Appendp(ctxt, spfix)
|
||||
pcdata := obj.Appendp(spfix, newprog)
|
||||
pcdata.Pos = cursym.Text.Pos
|
||||
pcdata.As = obj.APCDATA
|
||||
pcdata.From.Type = obj.TYPE_CONST
|
||||
@ -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.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.As = obj.ACALL
|
||||
call.To.Type = obj.TYPE_BRANCH
|
||||
@ -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
|
||||
// end (which following instructions are appended to).
|
||||
callend := call
|
||||
progedit(ctxt, callend)
|
||||
progedit(ctxt, callend, newprog)
|
||||
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.To.Type = obj.TYPE_BRANCH
|
||||
jmp.Pcond = cursym.Text.Link
|
||||
|
Loading…
x
Reference in New Issue
Block a user