diff options
Diffstat (limited to 'src/cmd/internal/obj/arm/obj5.go')
| -rw-r--r-- | src/cmd/internal/obj/arm/obj5.go | 137 |
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, |
