aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal/obj/arm64/obj7.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/internal/obj/arm64/obj7.go')
-rw-r--r--src/cmd/internal/obj/arm64/obj7.go307
1 files changed, 169 insertions, 138 deletions
diff --git a/src/cmd/internal/obj/arm64/obj7.go b/src/cmd/internal/obj/arm64/obj7.go
index 0baf51973a..8f7648e5d5 100644
--- a/src/cmd/internal/obj/arm64/obj7.go
+++ b/src/cmd/internal/obj/arm64/obj7.go
@@ -35,6 +35,7 @@ import (
"cmd/internal/objabi"
"cmd/internal/src"
"cmd/internal/sys"
+ "log"
"math"
)
@@ -621,25 +622,24 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
prologueEnd.Pos = prologueEnd.Pos.WithXlogue(src.PosPrologueEnd)
- if objabi.Framepointer_enabled {
- q1 = obj.Appendp(q1, c.newprog)
- q1.Pos = p.Pos
- q1.As = AMOVD
- q1.From.Type = obj.TYPE_REG
- q1.From.Reg = REGFP
- q1.To.Type = obj.TYPE_MEM
- q1.To.Reg = REGSP
- q1.To.Offset = -8
-
- q1 = obj.Appendp(q1, c.newprog)
- q1.Pos = p.Pos
- q1.As = ASUB
- q1.From.Type = obj.TYPE_CONST
- q1.From.Offset = 8
- q1.Reg = REGSP
- q1.To.Type = obj.TYPE_REG
- q1.To.Reg = REGFP
- }
+ // Frame pointer.
+ q1 = obj.Appendp(q1, c.newprog)
+ q1.Pos = p.Pos
+ q1.As = AMOVD
+ q1.From.Type = obj.TYPE_REG
+ q1.From.Reg = REGFP
+ q1.To.Type = obj.TYPE_MEM
+ q1.To.Reg = REGSP
+ q1.To.Offset = -8
+
+ q1 = obj.Appendp(q1, c.newprog)
+ q1.Pos = p.Pos
+ q1.As = ASUB
+ q1.From.Type = obj.TYPE_CONST
+ q1.From.Offset = 8
+ q1.Reg = REGSP
+ q1.To.Type = obj.TYPE_REG
+ q1.To.Reg = REGFP
if c.cursym.Func().Text.From.Sym.Wrapper() {
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
@@ -764,28 +764,26 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p.To.Reg = REGSP
p.Spadj = -c.autosize
- if objabi.Framepointer_enabled {
- p = obj.Appendp(p, c.newprog)
- p.As = ASUB
- p.From.Type = obj.TYPE_CONST
- p.From.Offset = 8
- p.Reg = REGSP
- p.To.Type = obj.TYPE_REG
- p.To.Reg = REGFP
- }
+ // Frame pointer.
+ p = obj.Appendp(p, c.newprog)
+ p.As = ASUB
+ p.From.Type = obj.TYPE_CONST
+ p.From.Offset = 8
+ p.Reg = REGSP
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = REGFP
}
} else {
/* want write-back pre-indexed SP+autosize -> SP, loading REGLINK*/
- if objabi.Framepointer_enabled {
- p.As = AMOVD
- p.From.Type = obj.TYPE_MEM
- p.From.Reg = REGSP
- p.From.Offset = -8
- p.To.Type = obj.TYPE_REG
- p.To.Reg = REGFP
- p = obj.Appendp(p, c.newprog)
- }
+ // Frame pointer.
+ p.As = AMOVD
+ p.From.Type = obj.TYPE_MEM
+ p.From.Reg = REGSP
+ p.From.Offset = -8
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = REGFP
+ p = obj.Appendp(p, c.newprog)
aoffset := c.autosize
@@ -820,6 +818,28 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
}
}
+ // If enabled, this code emits 'MOV PC, R27' before every 'MOV LR, PC',
+ // so that if you are debugging a low-level crash where PC and LR are zero,
+ // you can look at R27 to see what jumped to the zero.
+ // This is useful when bringing up Go on a new system.
+ // (There is similar code in ../ppc64/obj9.go:/if.false.)
+ const debugRETZERO = false
+ if debugRETZERO {
+ if p.As != obj.ARET {
+ q = newprog()
+ q.Pos = p.Pos
+ q.Link = p.Link
+ p.Link = q
+ p = q
+ }
+ p.As = AADR
+ p.From.Type = obj.TYPE_BRANCH
+ p.From.Offset = 0
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = REGTMP
+
+ }
+
if p.As != obj.ARET {
q = newprog()
q.Pos = p.Pos
@@ -865,109 +885,120 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
}
case obj.ADUFFCOPY:
- if objabi.Framepointer_enabled {
- // ADR ret_addr, R27
- // STP (FP, R27), -24(SP)
- // SUB 24, SP, FP
- // DUFFCOPY
- // ret_addr:
- // SUB 8, SP, FP
-
- q1 := p
- // copy DUFFCOPY from q1 to q4
- q4 := obj.Appendp(p, c.newprog)
- q4.Pos = p.Pos
- q4.As = obj.ADUFFCOPY
- q4.To = p.To
-
- q1.As = AADR
- q1.From.Type = obj.TYPE_BRANCH
- q1.To.Type = obj.TYPE_REG
- q1.To.Reg = REG_R27
-
- q2 := obj.Appendp(q1, c.newprog)
- q2.Pos = p.Pos
- q2.As = ASTP
- q2.From.Type = obj.TYPE_REGREG
- q2.From.Reg = REGFP
- q2.From.Offset = int64(REG_R27)
- q2.To.Type = obj.TYPE_MEM
- q2.To.Reg = REGSP
- q2.To.Offset = -24
-
- // maintaine FP for DUFFCOPY
- q3 := obj.Appendp(q2, c.newprog)
- q3.Pos = p.Pos
- q3.As = ASUB
- q3.From.Type = obj.TYPE_CONST
- q3.From.Offset = 24
- q3.Reg = REGSP
- q3.To.Type = obj.TYPE_REG
- q3.To.Reg = REGFP
-
- q5 := obj.Appendp(q4, c.newprog)
- q5.Pos = p.Pos
- q5.As = ASUB
- q5.From.Type = obj.TYPE_CONST
- q5.From.Offset = 8
- q5.Reg = REGSP
- q5.To.Type = obj.TYPE_REG
- q5.To.Reg = REGFP
- q1.From.SetTarget(q5)
- p = q5
- }
+ // ADR ret_addr, R27
+ // STP (FP, R27), -24(SP)
+ // SUB 24, SP, FP
+ // DUFFCOPY
+ // ret_addr:
+ // SUB 8, SP, FP
+
+ q1 := p
+ // copy DUFFCOPY from q1 to q4
+ q4 := obj.Appendp(p, c.newprog)
+ q4.Pos = p.Pos
+ q4.As = obj.ADUFFCOPY
+ q4.To = p.To
+
+ q1.As = AADR
+ q1.From.Type = obj.TYPE_BRANCH
+ q1.To.Type = obj.TYPE_REG
+ q1.To.Reg = REG_R27
+
+ q2 := obj.Appendp(q1, c.newprog)
+ q2.Pos = p.Pos
+ q2.As = ASTP
+ q2.From.Type = obj.TYPE_REGREG
+ q2.From.Reg = REGFP
+ q2.From.Offset = int64(REG_R27)
+ q2.To.Type = obj.TYPE_MEM
+ q2.To.Reg = REGSP
+ q2.To.Offset = -24
+
+ // maintain FP for DUFFCOPY
+ q3 := obj.Appendp(q2, c.newprog)
+ q3.Pos = p.Pos
+ q3.As = ASUB
+ q3.From.Type = obj.TYPE_CONST
+ q3.From.Offset = 24
+ q3.Reg = REGSP
+ q3.To.Type = obj.TYPE_REG
+ q3.To.Reg = REGFP
+
+ q5 := obj.Appendp(q4, c.newprog)
+ q5.Pos = p.Pos
+ q5.As = ASUB
+ q5.From.Type = obj.TYPE_CONST
+ q5.From.Offset = 8
+ q5.Reg = REGSP
+ q5.To.Type = obj.TYPE_REG
+ q5.To.Reg = REGFP
+ q1.From.SetTarget(q5)
+ p = q5
case obj.ADUFFZERO:
- if objabi.Framepointer_enabled {
- // ADR ret_addr, R27
- // STP (FP, R27), -24(SP)
- // SUB 24, SP, FP
- // DUFFZERO
- // ret_addr:
- // SUB 8, SP, FP
-
- q1 := p
- // copy DUFFZERO from q1 to q4
- q4 := obj.Appendp(p, c.newprog)
- q4.Pos = p.Pos
- q4.As = obj.ADUFFZERO
- q4.To = p.To
-
- q1.As = AADR
- q1.From.Type = obj.TYPE_BRANCH
- q1.To.Type = obj.TYPE_REG
- q1.To.Reg = REG_R27
-
- q2 := obj.Appendp(q1, c.newprog)
- q2.Pos = p.Pos
- q2.As = ASTP
- q2.From.Type = obj.TYPE_REGREG
- q2.From.Reg = REGFP
- q2.From.Offset = int64(REG_R27)
- q2.To.Type = obj.TYPE_MEM
- q2.To.Reg = REGSP
- q2.To.Offset = -24
-
- // maintaine FP for DUFFZERO
- q3 := obj.Appendp(q2, c.newprog)
- q3.Pos = p.Pos
- q3.As = ASUB
- q3.From.Type = obj.TYPE_CONST
- q3.From.Offset = 24
- q3.Reg = REGSP
- q3.To.Type = obj.TYPE_REG
- q3.To.Reg = REGFP
-
- q5 := obj.Appendp(q4, c.newprog)
- q5.Pos = p.Pos
- q5.As = ASUB
- q5.From.Type = obj.TYPE_CONST
- q5.From.Offset = 8
- q5.Reg = REGSP
- q5.To.Type = obj.TYPE_REG
- q5.To.Reg = REGFP
- q1.From.SetTarget(q5)
- p = q5
+ // ADR ret_addr, R27
+ // STP (FP, R27), -24(SP)
+ // SUB 24, SP, FP
+ // DUFFZERO
+ // ret_addr:
+ // SUB 8, SP, FP
+
+ q1 := p
+ // copy DUFFZERO from q1 to q4
+ q4 := obj.Appendp(p, c.newprog)
+ q4.Pos = p.Pos
+ q4.As = obj.ADUFFZERO
+ q4.To = p.To
+
+ q1.As = AADR
+ q1.From.Type = obj.TYPE_BRANCH
+ q1.To.Type = obj.TYPE_REG
+ q1.To.Reg = REG_R27
+
+ q2 := obj.Appendp(q1, c.newprog)
+ q2.Pos = p.Pos
+ q2.As = ASTP
+ q2.From.Type = obj.TYPE_REGREG
+ q2.From.Reg = REGFP
+ q2.From.Offset = int64(REG_R27)
+ q2.To.Type = obj.TYPE_MEM
+ q2.To.Reg = REGSP
+ q2.To.Offset = -24
+
+ // maintain FP for DUFFZERO
+ q3 := obj.Appendp(q2, c.newprog)
+ q3.Pos = p.Pos
+ q3.As = ASUB
+ q3.From.Type = obj.TYPE_CONST
+ q3.From.Offset = 24
+ q3.Reg = REGSP
+ q3.To.Type = obj.TYPE_REG
+ q3.To.Reg = REGFP
+
+ q5 := obj.Appendp(q4, c.newprog)
+ q5.Pos = p.Pos
+ q5.As = ASUB
+ q5.From.Type = obj.TYPE_CONST
+ q5.From.Offset = 8
+ q5.Reg = REGSP
+ q5.To.Type = obj.TYPE_REG
+ q5.To.Reg = REGFP
+ q1.From.SetTarget(q5)
+ p = q5
+ }
+
+ if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.Spadj == 0 {
+ f := c.cursym.Func()
+ if f.FuncFlag&objabi.FuncFlag_SPWRITE == 0 {
+ c.cursym.Func().FuncFlag |= objabi.FuncFlag_SPWRITE
+ if ctxt.Debugvlog || !ctxt.IsAsm {
+ ctxt.Logf("auto-SPWRITE: %s %v\n", c.cursym.Name, p)
+ if !ctxt.IsAsm {
+ ctxt.Diag("invalid auto-SPWRITE in non-assembly")
+ ctxt.DiagFlush()
+ log.Fatalf("bad SPWRITE")
+ }
+ }
}
}
}