aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal/obj/arm/obj5.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/internal/obj/arm/obj5.go')
-rw-r--r--src/cmd/internal/obj/arm/obj5.go137
1 files changed, 60 insertions, 77 deletions
diff --git a/src/cmd/internal/obj/arm/obj5.go b/src/cmd/internal/obj/arm/obj5.go
index 89cf299bef..bf4ad0a69b 100644
--- a/src/cmd/internal/obj/arm/obj5.go
+++ b/src/cmd/internal/obj/arm/obj5.go
@@ -41,12 +41,11 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
p.From.Class = 0
p.To.Class = 0
+ c := ctxt5{ctxt: ctxt, newprog: newprog}
+
// Rewrite B/BL to symbol as TYPE_BRANCH.
switch p.As {
- case AB,
- ABL,
- obj.ADUFFZERO,
- obj.ADUFFCOPY:
+ case AB, ABL, obj.ADUFFZERO, obj.ADUFFCOPY:
if p.To.Type == obj.TYPE_MEM && (p.To.Name == obj.NAME_EXTERN || p.To.Name == obj.NAME_STATIC) && p.To.Sym != nil {
p.To.Type = obj.TYPE_BRANCH
}
@@ -104,7 +103,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
// Rewrite float constants to values stored in memory.
switch p.As {
case AMOVF:
- if p.From.Type == obj.TYPE_FCONST && chipfloat5(ctxt, p.From.Val.(float64)) < 0 && (chipzero5(ctxt, p.From.Val.(float64)) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) {
+ if p.From.Type == obj.TYPE_FCONST && c.chipfloat5(p.From.Val.(float64)) < 0 && (c.chipzero5(p.From.Val.(float64)) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) {
f32 := float32(p.From.Val.(float64))
p.From.Type = obj.TYPE_MEM
p.From.Sym = ctxt.Float32Sym(f32)
@@ -113,7 +112,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
}
case AMOVD:
- if p.From.Type == obj.TYPE_FCONST && chipfloat5(ctxt, p.From.Val.(float64)) < 0 && (chipzero5(ctxt, p.From.Val.(float64)) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) {
+ if p.From.Type == obj.TYPE_FCONST && c.chipfloat5(p.From.Val.(float64)) < 0 && (c.chipzero5(p.From.Val.(float64)) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) {
p.From.Type = obj.TYPE_MEM
p.From.Sym = ctxt.Float64Sym(p.From.Val.(float64))
p.From.Name = obj.NAME_EXTERN
@@ -122,12 +121,12 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
}
if ctxt.Flag_dynlink {
- rewriteToUseGot(ctxt, p, newprog)
+ c.rewriteToUseGot(p)
}
}
// Rewrite p, if necessary, to access global data via the global offset table.
-func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
+func (c *ctxt5) rewriteToUseGot(p *obj.Prog) {
if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO {
// ADUFFxxx $offset
// becomes
@@ -136,9 +135,9 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
// CALL (R9)
var sym *obj.LSym
if p.As == obj.ADUFFZERO {
- sym = ctxt.Lookup("runtime.duffzero", 0)
+ sym = c.ctxt.Lookup("runtime.duffzero", 0)
} else {
- sym = ctxt.Lookup("runtime.duffcopy", 0)
+ sym = c.ctxt.Lookup("runtime.duffcopy", 0)
}
offset := p.To.Offset
p.As = AMOVW
@@ -150,13 +149,13 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
p.To.Name = obj.NAME_NONE
p.To.Offset = 0
p.To.Sym = nil
- p1 := obj.Appendp(p, newprog)
+ p1 := obj.Appendp(p, c.newprog)
p1.As = AADD
p1.From.Type = obj.TYPE_CONST
p1.From.Offset = offset
p1.To.Type = obj.TYPE_REG
p1.To.Reg = REG_R9
- p2 := obj.Appendp(p1, newprog)
+ p2 := obj.Appendp(p1, c.newprog)
p2.As = obj.ACALL
p2.To.Type = obj.TYPE_MEM
p2.To.Reg = REG_R9
@@ -170,15 +169,15 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
// MOVW $sym, Rx becomes MOVW sym@GOT, Rx
// MOVW $sym+<off>, Rx becomes MOVW sym@GOT, Rx; ADD <off>, Rx
if p.As != AMOVW {
- ctxt.Diag("do not know how to handle TYPE_ADDR in %v with -dynlink", p)
+ c.ctxt.Diag("do not know how to handle TYPE_ADDR in %v with -dynlink", p)
}
if p.To.Type != obj.TYPE_REG {
- ctxt.Diag("do not know how to handle LEAQ-type insn to non-register in %v with -dynlink", p)
+ c.ctxt.Diag("do not know how to handle LEAQ-type insn to non-register in %v with -dynlink", p)
}
p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_GOTREF
if p.From.Offset != 0 {
- q := obj.Appendp(p, newprog)
+ q := obj.Appendp(p, c.newprog)
q.As = AADD
q.From.Type = obj.TYPE_CONST
q.From.Offset = p.From.Offset
@@ -187,7 +186,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
}
}
if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN {
- ctxt.Diag("don't know how to handle %v with -dynlink", p)
+ c.ctxt.Diag("don't know how to handle %v with -dynlink", p)
}
var source *obj.Addr
// MOVx sym, Ry becomes MOVW sym@GOT, R9; MOVx (R9), Ry
@@ -195,7 +194,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
// An addition may be inserted between the two MOVs if there is an offset.
if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
- ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p)
+ c.ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p)
}
source = &p.From
} else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
@@ -210,10 +209,10 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
return
}
if source.Type != obj.TYPE_MEM {
- ctxt.Diag("don't know how to handle %v with -dynlink", p)
+ c.ctxt.Diag("don't know how to handle %v with -dynlink", p)
}
- p1 := obj.Appendp(p, newprog)
- p2 := obj.Appendp(p1, newprog)
+ p1 := obj.Appendp(p, c.newprog)
+ p2 := obj.Appendp(p1, c.newprog)
p1.As = AMOVW
p1.From.Type = obj.TYPE_MEM
@@ -249,15 +248,15 @@ const (
func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
autosize := int32(0)
- ctxt.Cursym = cursym
-
if cursym.Text == nil || cursym.Text.Link == nil {
return
}
- softfloat(ctxt, newprog, cursym)
+ c := ctxt5{ctxt: ctxt, cursym: cursym, newprog: newprog}
- p := cursym.Text
+ c.softfloat()
+
+ p := c.cursym.Text
autoffset := int32(p.To.Offset)
if autoffset < 0 {
autoffset = 0
@@ -283,9 +282,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
case ADIV, ADIVU, AMOD, AMODU:
q = p
- if ctxt.Sym_div == nil {
- initdiv(ctxt)
- }
cursym.Text.Mark &^= LEAF
continue
@@ -362,11 +358,11 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
}
if p.From3.Offset&obj.NOSPLIT == 0 {
- p = stacksplit(ctxt, p, newprog, autosize) // emit split check
+ p = c.stacksplit(p, autosize) // emit split check
}
// MOVW.W R14,$-autosize(SP)
- p = obj.Appendp(p, newprog)
+ p = obj.Appendp(p, c.newprog)
p.As = AMOVW
p.Scond |= C_WBIT
@@ -597,16 +593,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p.To.Type = obj.TYPE_BRANCH
switch o {
case ADIV:
- p.To.Sym = ctxt.Sym_div
-
+ p.To.Sym = symdiv
case ADIVU:
- p.To.Sym = ctxt.Sym_divu
-
+ p.To.Sym = symdivu
case AMOD:
- p.To.Sym = ctxt.Sym_mod
-
+ p.To.Sym = symmod
case AMODU:
- p.To.Sym = ctxt.Sym_modu
+ p.To.Sym = symmodu
}
/* MOV REGTMP, b */
@@ -637,21 +630,21 @@ func isfloatreg(a *obj.Addr) bool {
return a.Type == obj.TYPE_REG && REG_F0 <= a.Reg && a.Reg <= REG_F15
}
-func softfloat(ctxt *obj.Link, newprog obj.ProgAlloc, cursym *obj.LSym) {
+func (c *ctxt5) softfloat() {
if obj.GOARM > 5 {
return
}
- symsfloat := ctxt.Lookup("_sfloat", 0)
+ symsfloat := c.ctxt.Lookup("_sfloat", 0)
wasfloat := 0
- for p := cursym.Text; p != nil; p = p.Link {
+ for p := c.cursym.Text; p != nil; p = p.Link {
if p.Pcond != nil {
p.Pcond.Mark |= LABEL
}
}
var next *obj.Prog
- for p := cursym.Text; p != nil; p = p.Link {
+ for p := c.cursym.Text; p != nil; p = p.Link {
switch p.As {
case AMOVW:
if isfloatreg(&p.To) || isfloatreg(&p.From) {
@@ -691,12 +684,12 @@ func softfloat(ctxt *obj.Link, newprog obj.ProgAlloc, cursym *obj.LSym) {
soft:
if wasfloat == 0 || (p.Mark&LABEL != 0) {
- next = newprog()
+ next = c.newprog()
*next = *p
// BL _sfloat(SB)
*p = obj.Prog{}
- p.Ctxt = ctxt
+ p.Ctxt = c.ctxt
p.Link = next
p.As = ABL
p.To.Type = obj.TYPE_BRANCH
@@ -714,16 +707,16 @@ func softfloat(ctxt *obj.Link, newprog obj.ProgAlloc, cursym *obj.LSym) {
}
}
-func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize int32) *obj.Prog {
+func (c *ctxt5) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
// MOVW g_stackguard(g), R1
- p = obj.Appendp(p, newprog)
+ p = obj.Appendp(p, c.newprog)
p.As = AMOVW
p.From.Type = obj.TYPE_MEM
p.From.Reg = REGG
- p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
- if ctxt.Cursym.CFunc() {
- p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
+ p.From.Offset = 2 * int64(c.ctxt.Arch.PtrSize) // G.stackguard0
+ if c.cursym.CFunc() {
+ p.From.Offset = 3 * int64(c.ctxt.Arch.PtrSize) // G.stackguard1
}
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R1
@@ -731,7 +724,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
if framesize <= obj.StackSmall {
// small stack: SP < stackguard
// CMP stackguard, SP
- p = obj.Appendp(p, newprog)
+ p = obj.Appendp(p, c.newprog)
p.As = ACMP
p.From.Type = obj.TYPE_REG
@@ -741,7 +734,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
// large stack: SP-framesize < stackguard-StackSmall
// MOVW $-(framesize-StackSmall)(SP), R2
// CMP stackguard, R2
- p = obj.Appendp(p, newprog)
+ p = obj.Appendp(p, c.newprog)
p.As = AMOVW
p.From.Type = obj.TYPE_ADDR
@@ -750,7 +743,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2
- p = obj.Appendp(p, newprog)
+ p = obj.Appendp(p, c.newprog)
p.As = ACMP
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1
@@ -766,14 +759,14 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
// SUB.NE R1, R2
// MOVW.NE $(framesize+(StackGuard-StackSmall)), R3
// CMP.NE R3, R2
- p = obj.Appendp(p, newprog)
+ p = obj.Appendp(p, c.newprog)
p.As = ACMP
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1)))
p.Reg = REG_R1
- p = obj.Appendp(p, newprog)
+ p = obj.Appendp(p, c.newprog)
p.As = AMOVW
p.From.Type = obj.TYPE_ADDR
p.From.Reg = REGSP
@@ -782,7 +775,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
p.To.Reg = REG_R2
p.Scond = C_SCOND_NE
- p = obj.Appendp(p, newprog)
+ p = obj.Appendp(p, c.newprog)
p.As = ASUB
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1
@@ -790,7 +783,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
p.To.Reg = REG_R2
p.Scond = C_SCOND_NE
- p = obj.Appendp(p, newprog)
+ p = obj.Appendp(p, c.newprog)
p.As = AMOVW
p.From.Type = obj.TYPE_ADDR
p.From.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall)
@@ -798,7 +791,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
p.To.Reg = REG_R3
p.Scond = C_SCOND_NE
- p = obj.Appendp(p, newprog)
+ p = obj.Appendp(p, c.newprog)
p.As = ACMP
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3
@@ -807,23 +800,23 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
}
// BLS call-to-morestack
- bls := obj.Appendp(p, newprog)
+ bls := obj.Appendp(p, c.newprog)
bls.As = ABLS
bls.To.Type = obj.TYPE_BRANCH
var last *obj.Prog
- for last = ctxt.Cursym.Text; last.Link != nil; last = last.Link {
+ for last = c.cursym.Text; last.Link != nil; last = last.Link {
}
// Now we are at the end of the function, but logically
// we are still in function prologue. We need to fix the
// SP data and PCDATA.
- spfix := obj.Appendp(last, newprog)
+ spfix := obj.Appendp(last, c.newprog)
spfix.As = obj.ANOP
spfix.Spadj = -framesize
- pcdata := obj.Appendp(spfix, newprog)
- pcdata.Pos = ctxt.Cursym.Text.Pos
+ pcdata := obj.Appendp(spfix, c.newprog)
+ pcdata.Pos = c.cursym.Text.Pos
pcdata.As = obj.APCDATA
pcdata.From.Type = obj.TYPE_CONST
pcdata.From.Offset = obj.PCDATA_StackMapIndex
@@ -831,7 +824,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
pcdata.To.Offset = -1 // pcdata starts at -1 at function entry
// MOVW LR, R3
- movw := obj.Appendp(pcdata, newprog)
+ movw := obj.Appendp(pcdata, c.newprog)
movw.As = AMOVW
movw.From.Type = obj.TYPE_REG
movw.From.Reg = REGLINK
@@ -841,38 +834,28 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize in
bls.Pcond = movw
// BL runtime.morestack
- call := obj.Appendp(movw, newprog)
+ call := obj.Appendp(movw, c.newprog)
call.As = obj.ACALL
call.To.Type = obj.TYPE_BRANCH
morestack := "runtime.morestack"
switch {
- case ctxt.Cursym.CFunc():
+ case c.cursym.CFunc():
morestack = "runtime.morestackc"
- case ctxt.Cursym.Text.From3.Offset&obj.NEEDCTXT == 0:
+ case c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0:
morestack = "runtime.morestack_noctxt"
}
- call.To.Sym = ctxt.Lookup(morestack, 0)
+ call.To.Sym = c.ctxt.Lookup(morestack, 0)
// B start
- b := obj.Appendp(call, newprog)
+ b := obj.Appendp(call, c.newprog)
b.As = obj.AJMP
b.To.Type = obj.TYPE_BRANCH
- b.Pcond = ctxt.Cursym.Text.Link
+ b.Pcond = c.cursym.Text.Link
b.Spadj = +framesize
return bls
}
-func initdiv(ctxt *obj.Link) {
- if ctxt.Sym_div != nil {
- return
- }
- ctxt.Sym_div = ctxt.Lookup("_div", 0)
- ctxt.Sym_divu = ctxt.Lookup("_divu", 0)
- ctxt.Sym_mod = ctxt.Lookup("_mod", 0)
- ctxt.Sym_modu = ctxt.Lookup("_modu", 0)
-}
-
var unaryDst = map[obj.As]bool{
ASWI: true,
AWORD: true,