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