]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj: remove Follow pass
authorCherry Zhang <cherryyz@google.com>
Thu, 2 Feb 2017 14:44:26 +0000 (09:44 -0500)
committerCherry Zhang <cherryyz@google.com>
Tue, 7 Feb 2017 15:00:48 +0000 (15:00 +0000)
The Follow pass in the assembler backend reorders and copies
instructions. This even applies to hand-written assembly code,
which in many cases don't want to be reordered. Now that the
SSA compiler does a good job for laying out instructions, the
benefit of this pass is very little:

AMD64: (old = with Follow, new = without Follow)
name                      old time/op    new time/op    delta
BinaryTree17-12              2.78s ± 1%     2.79s ± 1%  +0.44%  (p=0.000 n=20+19)
Fannkuch11-12                3.11s ± 0%     3.31s ± 1%  +6.16%  (p=0.000 n=19+19)
FmtFprintfEmpty-12          50.9ns ± 1%    51.6ns ± 3%  +1.40%  (p=0.000 n=17+20)
FmtFprintfString-12          127ns ± 0%     128ns ± 1%  +0.88%  (p=0.000 n=17+17)
FmtFprintfInt-12             122ns ± 0%     123ns ± 1%  +0.76%  (p=0.000 n=20+19)
FmtFprintfIntInt-12          185ns ± 1%     186ns ± 1%  +0.65%  (p=0.000 n=20+19)
FmtFprintfPrefixedInt-12     192ns ± 1%     202ns ± 1%  +4.99%  (p=0.000 n=20+19)
FmtFprintfFloat-12           284ns ± 0%     288ns ± 0%  +1.33%  (p=0.000 n=15+19)
FmtManyArgs-12               807ns ± 0%     804ns ± 0%  -0.44%  (p=0.000 n=16+18)
GobDecode-12                7.23ms ± 1%    7.21ms ± 1%    ~     (p=0.052 n=20+20)
GobEncode-12                6.09ms ± 1%    6.12ms ± 1%  +0.41%  (p=0.002 n=19+19)
Gzip-12                      253ms ± 1%     255ms ± 1%  +0.95%  (p=0.000 n=18+20)
Gunzip-12                   38.4ms ± 0%    38.5ms ± 0%  +0.34%  (p=0.000 n=17+17)
HTTPClientServer-12         95.4µs ± 2%    96.1µs ± 1%  +0.78%  (p=0.002 n=19+19)
JSONEncode-12               16.5ms ± 1%    16.6ms ± 1%  +1.17%  (p=0.000 n=19+19)
JSONDecode-12               54.6ms ± 1%    55.3ms ± 1%  +1.23%  (p=0.000 n=18+18)
Mandelbrot200-12            4.47ms ± 0%    4.47ms ± 0%  +0.06%  (p=0.000 n=18+18)
GoParse-12                  3.47ms ± 1%    3.47ms ± 1%    ~     (p=0.583 n=20+20)
RegexpMatchEasy0_32-12      84.8ns ± 1%    85.2ns ± 2%  +0.51%  (p=0.022 n=20+20)
RegexpMatchEasy0_1K-12       206ns ± 1%     206ns ± 1%    ~     (p=0.770 n=20+20)
RegexpMatchEasy1_32-12      82.8ns ± 1%    83.4ns ± 1%  +0.64%  (p=0.000 n=20+19)
RegexpMatchEasy1_1K-12       363ns ± 1%     361ns ± 1%  -0.48%  (p=0.007 n=20+20)
RegexpMatchMedium_32-12      126ns ± 1%     126ns ± 0%  +0.72%  (p=0.000 n=20+20)
RegexpMatchMedium_1K-12     39.1µs ± 1%    39.8µs ± 0%  +1.73%  (p=0.000 n=19+19)
RegexpMatchHard_32-12       1.97µs ± 0%    1.98µs ± 1%  +0.29%  (p=0.005 n=18+20)
RegexpMatchHard_1K-12       59.5µs ± 1%    59.8µs ± 1%  +0.36%  (p=0.000 n=18+20)
Revcomp-12                   442ms ± 1%     445ms ± 2%  +0.67%  (p=0.000 n=19+20)
Template-12                 58.0ms ± 1%    57.5ms ± 1%  -0.85%  (p=0.000 n=19+19)
TimeParse-12                 311ns ± 0%     314ns ± 0%  +0.94%  (p=0.000 n=20+18)
TimeFormat-12                350ns ± 3%     346ns ± 0%    ~     (p=0.076 n=20+19)
[Geo mean]                  55.9µs         56.4µs       +0.80%

ARM32:
name                     old time/op    new time/op    delta
BinaryTree17-4              30.4s ± 0%     30.1s ± 0%  -1.14%  (p=0.000 n=10+8)
Fannkuch11-4                13.7s ± 0%     13.6s ± 0%  -0.75%  (p=0.000 n=10+10)
FmtFprintfEmpty-4           664ns ± 1%     651ns ± 1%  -1.96%  (p=0.000 n=7+8)
FmtFprintfString-4         1.83µs ± 2%    1.77µs ± 2%  -3.21%  (p=0.000 n=10+10)
FmtFprintfInt-4            1.57µs ± 2%    1.54µs ± 2%  -2.25%  (p=0.007 n=10+10)
FmtFprintfIntInt-4         2.37µs ± 2%    2.31µs ± 1%  -2.68%  (p=0.000 n=10+10)
FmtFprintfPrefixedInt-4    2.14µs ± 2%    2.10µs ± 1%  -1.83%  (p=0.006 n=10+10)
FmtFprintfFloat-4          3.69µs ± 2%    3.74µs ± 1%  +1.60%  (p=0.000 n=10+10)
FmtManyArgs-4              9.43µs ± 1%    9.17µs ± 1%  -2.70%  (p=0.000 n=10+10)
GobDecode-4                76.3ms ± 1%    75.5ms ± 1%  -1.14%  (p=0.003 n=10+10)
GobEncode-4                70.7ms ± 2%    69.0ms ± 1%  -2.36%  (p=0.000 n=10+10)
Gzip-4                      2.64s ± 1%     2.65s ± 0%  +0.59%  (p=0.002 n=10+10)
Gunzip-4                    402ms ± 0%     398ms ± 0%  -1.11%  (p=0.000 n=10+9)
HTTPClientServer-4          458µs ± 0%     457µs ± 0%    ~     (p=0.247 n=10+10)
JSONEncode-4                171ms ± 0%     172ms ± 0%  +0.56%  (p=0.000 n=10+10)
JSONDecode-4                672ms ± 1%     668ms ± 1%    ~     (p=0.105 n=10+10)
Mandelbrot200-4            33.5ms ± 0%    33.5ms ± 0%    ~     (p=0.156 n=9+10)
GoParse-4                  33.9ms ± 0%    34.0ms ± 0%  +0.36%  (p=0.031 n=9+9)
RegexpMatchEasy0_32-4       823ns ± 1%     835ns ± 1%  +1.49%  (p=0.000 n=8+8)
RegexpMatchEasy0_1K-4      3.99µs ± 0%    4.02µs ± 1%  +0.92%  (p=0.000 n=8+10)
RegexpMatchEasy1_32-4       877ns ± 3%     904ns ± 2%  +3.07%  (p=0.012 n=10+10)
RegexpMatchEasy1_1K-4      5.99µs ± 0%    5.97µs ± 1%  -0.38%  (p=0.023 n=8+8)
RegexpMatchMedium_32-4     1.40µs ± 2%    1.40µs ± 2%    ~     (p=0.590 n=10+9)
RegexpMatchMedium_1K-4      357µs ± 0%     355µs ± 1%  -0.72%  (p=0.000 n=7+8)
RegexpMatchHard_32-4       22.3µs ± 0%    22.1µs ± 0%  -0.49%  (p=0.000 n=8+7)
RegexpMatchHard_1K-4        661µs ± 0%     658µs ± 0%  -0.42%  (p=0.000 n=8+7)
Revcomp-4                  46.3ms ± 0%    46.3ms ± 0%    ~     (p=0.393 n=10+10)
Template-4                  753ms ± 1%     750ms ± 0%    ~     (p=0.211 n=10+9)
TimeParse-4                4.28µs ± 1%    4.22µs ± 1%  -1.34%  (p=0.000 n=8+10)
TimeFormat-4               9.00µs ± 0%    9.05µs ± 0%  +0.59%  (p=0.000 n=10+10)
[Geo mean]                  538µs          535µs       -0.55%

ARM64:
name                     old time/op    new time/op    delta
BinaryTree17-8              8.39s ± 0%     8.39s ± 0%    ~     (p=0.684 n=10+10)
Fannkuch11-8                5.95s ± 0%     5.99s ± 0%  +0.63%  (p=0.000 n=10+10)
FmtFprintfEmpty-8           116ns ± 0%     116ns ± 0%    ~     (all equal)
FmtFprintfString-8          361ns ± 0%     360ns ± 0%  -0.31%  (p=0.003 n=8+6)
FmtFprintfInt-8             290ns ± 0%     290ns ± 0%    ~     (p=0.620 n=9+9)
FmtFprintfIntInt-8          476ns ± 1%     469ns ± 0%  -1.47%  (p=0.000 n=10+6)
FmtFprintfPrefixedInt-8     412ns ± 2%     417ns ± 2%  +1.39%  (p=0.006 n=9+10)
FmtFprintfFloat-8           652ns ± 1%     652ns ± 0%    ~     (p=0.161 n=10+8)
FmtManyArgs-8              1.94µs ± 0%    1.94µs ± 2%    ~     (p=0.781 n=10+10)
GobDecode-8                17.7ms ± 1%    17.7ms ± 0%    ~     (p=0.962 n=10+7)
GobEncode-8                15.6ms ± 0%    15.6ms ± 1%    ~     (p=0.063 n=10+10)
Gzip-8                      786ms ± 0%     787ms ± 0%    ~     (p=0.356 n=10+9)
Gunzip-8                    127ms ± 0%     127ms ± 0%  +0.08%  (p=0.028 n=10+9)
HTTPClientServer-8          198µs ± 6%     198µs ± 7%    ~     (p=0.796 n=10+10)
JSONEncode-8               42.5ms ± 0%    42.2ms ± 0%  -0.73%  (p=0.000 n=9+8)
JSONDecode-8                158ms ± 1%     162ms ± 0%  +2.28%  (p=0.000 n=10+9)
Mandelbrot200-8            10.1ms ± 0%    10.1ms ± 0%  -0.01%  (p=0.000 n=10+9)
GoParse-8                  8.54ms ± 1%    8.63ms ± 1%  +1.06%  (p=0.000 n=10+9)
RegexpMatchEasy0_32-8       231ns ± 1%     225ns ± 0%  -2.52%  (p=0.000 n=9+10)
RegexpMatchEasy0_1K-8      1.63µs ± 0%    1.63µs ± 0%    ~     (p=0.170 n=10+10)
RegexpMatchEasy1_32-8       253ns ± 0%     249ns ± 0%  -1.41%  (p=0.000 n=9+10)
RegexpMatchEasy1_1K-8      2.08µs ± 0%    2.08µs ± 0%  -0.32%  (p=0.000 n=9+10)
RegexpMatchMedium_32-8      355ns ± 1%     351ns ± 0%  -1.04%  (p=0.007 n=10+7)
RegexpMatchMedium_1K-8      104µs ± 0%     104µs ± 0%    ~     (p=0.148 n=10+10)
RegexpMatchHard_32-8       5.79µs ± 0%    5.79µs ± 0%    ~     (p=0.578 n=10+10)
RegexpMatchHard_1K-8        176µs ± 0%     176µs ± 0%    ~     (p=0.137 n=10+10)
Revcomp-8                   1.37s ± 1%     1.36s ± 1%  -0.26%  (p=0.023 n=10+10)
Template-8                  151ms ± 1%     154ms ± 1%  +2.14%  (p=0.000 n=9+10)
TimeParse-8                 723ns ± 2%     721ns ± 1%    ~     (p=0.592 n=10+10)
TimeFormat-8                804ns ± 2%     798ns ± 3%    ~     (p=0.344 n=10+10)
[Geo mean]                  154µs          154µs       -0.02%

Therefore remove this pass. Also reduce text size by 0.5~2%.

Comment out some dead code in runtime/sys_nacl_amd64p32.s
which contains undefined symbols.

Change-Id: I1473986fe5b18b3d2554ce96cdc6f0999b8d955d
Reviewed-on: https://go-review.googlesource.com/36205
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/internal/obj/arm/obj5.go
src/cmd/internal/obj/arm64/obj7.go
src/cmd/internal/obj/link.go
src/cmd/internal/obj/mips/obj0.go
src/cmd/internal/obj/plist.go
src/cmd/internal/obj/ppc64/obj9.go
src/cmd/internal/obj/s390x/objz.go
src/cmd/internal/obj/x86/obj6.go
src/runtime/sys_nacl_amd64p32.s

index 0bf80143982ae67d89c4cef21713dd586788c695..75d22bcf810a05dc50e2bfbd03d6f3f74c24d8e5 100644 (file)
@@ -34,7 +34,6 @@ import (
        "cmd/internal/obj"
        "cmd/internal/sys"
        "fmt"
-       "log"
        "math"
 )
 
@@ -862,183 +861,6 @@ func initdiv(ctxt *obj.Link) {
        ctxt.Sym_modu = obj.Linklookup(ctxt, "_modu", 0)
 }
 
-func follow(ctxt *obj.Link, s *obj.LSym) {
-       ctxt.Cursym = s
-
-       firstp := ctxt.NewProg()
-       lastp := firstp
-       xfol(ctxt, s.Text, &lastp)
-       lastp.Link = nil
-       s.Text = firstp.Link
-}
-
-func relinv(a obj.As) obj.As {
-       switch a {
-       case ABEQ:
-               return ABNE
-       case ABNE:
-               return ABEQ
-       case ABCS:
-               return ABCC
-       case ABHS:
-               return ABLO
-       case ABCC:
-               return ABCS
-       case ABLO:
-               return ABHS
-       case ABMI:
-               return ABPL
-       case ABPL:
-               return ABMI
-       case ABVS:
-               return ABVC
-       case ABVC:
-               return ABVS
-       case ABHI:
-               return ABLS
-       case ABLS:
-               return ABHI
-       case ABGE:
-               return ABLT
-       case ABLT:
-               return ABGE
-       case ABGT:
-               return ABLE
-       case ABLE:
-               return ABGT
-       }
-
-       log.Fatalf("unknown relation: %s", Anames[a])
-       return 0
-}
-
-func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) {
-       var q *obj.Prog
-       var r *obj.Prog
-       var i int
-
-loop:
-       if p == nil {
-               return
-       }
-       a := p.As
-       if a == AB {
-               q = p.Pcond
-               if q != nil && q.As != obj.ATEXT {
-                       p.Mark |= FOLL
-                       p = q
-                       if p.Mark&FOLL == 0 {
-                               goto loop
-                       }
-               }
-       }
-
-       if p.Mark&FOLL != 0 {
-               i = 0
-               q = p
-               for ; i < 4; i, q = i+1, q.Link {
-                       if q == *last || q == nil {
-                               break
-                       }
-                       a = q.As
-                       if a == obj.ANOP {
-                               i--
-                               continue
-                       }
-
-                       if a == AB || (a == obj.ARET && q.Scond == C_SCOND_NONE) || a == ARFE || a == obj.AUNDEF {
-                               goto copy
-                       }
-                       if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) {
-                               continue
-                       }
-                       if a != ABEQ && a != ABNE {
-                               continue
-                       }
-
-               copy:
-                       for {
-                               r = ctxt.NewProg()
-                               *r = *p
-                               if r.Mark&FOLL == 0 {
-                                       fmt.Printf("can't happen 1\n")
-                               }
-                               r.Mark |= FOLL
-                               if p != q {
-                                       p = p.Link
-                                       (*last).Link = r
-                                       *last = r
-                                       continue
-                               }
-
-                               (*last).Link = r
-                               *last = r
-                               if a == AB || (a == obj.ARET && q.Scond == C_SCOND_NONE) || a == ARFE || a == obj.AUNDEF {
-                                       return
-                               }
-                               r.As = ABNE
-                               if a == ABNE {
-                                       r.As = ABEQ
-                               }
-                               r.Pcond = p.Link
-                               r.Link = p.Pcond
-                               if r.Link.Mark&FOLL == 0 {
-                                       xfol(ctxt, r.Link, last)
-                               }
-                               if r.Pcond.Mark&FOLL == 0 {
-                                       fmt.Printf("can't happen 2\n")
-                               }
-                               return
-                       }
-               }
-
-               a = AB
-               q = ctxt.NewProg()
-               q.As = a
-               q.Pos = p.Pos
-               q.To.Type = obj.TYPE_BRANCH
-               q.To.Offset = p.Pc
-               q.Pcond = p
-               p = q
-       }
-
-       p.Mark |= FOLL
-       (*last).Link = p
-       *last = p
-       if a == AB || (a == obj.ARET && p.Scond == C_SCOND_NONE) || a == ARFE || a == obj.AUNDEF {
-               return
-       }
-
-       if p.Pcond != nil {
-               if a != ABL && a != ABX && p.Link != nil {
-                       q = obj.Brchain(ctxt, p.Link)
-                       if a != obj.ATEXT {
-                               if q != nil && (q.Mark&FOLL != 0) {
-                                       p.As = relinv(a)
-                                       p.Link = p.Pcond
-                                       p.Pcond = q
-                               }
-                       }
-
-                       xfol(ctxt, p.Link, last)
-                       q = obj.Brchain(ctxt, p.Pcond)
-                       if q == nil {
-                               q = p.Pcond
-                       }
-                       if q.Mark&FOLL != 0 {
-                               p.Pcond = q
-                               return
-                       }
-
-                       p = q
-                       goto loop
-               }
-       }
-
-       p = p.Link
-       goto loop
-}
-
 var unaryDst = map[obj.As]bool{
        ASWI:  true,
        AWORD: true,
@@ -1048,7 +870,6 @@ var Linkarm = obj.LinkArch{
        Arch:       sys.ArchARM,
        Preprocess: preprocess,
        Assemble:   span5,
-       Follow:     follow,
        Progedit:   progedit,
        UnaryDst:   unaryDst,
 }
index f70ca345ed4ed5ac058058580af49a1f795b5d03..f68964ab496e6141e100159901045724d40c2d42 100644 (file)
@@ -34,7 +34,6 @@ import (
        "cmd/internal/obj"
        "cmd/internal/sys"
        "fmt"
-       "log"
        "math"
 )
 
@@ -443,191 +442,6 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
        obj.Nopout(p)
 }
 
-func follow(ctxt *obj.Link, s *obj.LSym) {
-       ctxt.Cursym = s
-
-       firstp := ctxt.NewProg()
-       lastp := firstp
-       xfol(ctxt, s.Text, &lastp)
-       lastp.Link = nil
-       s.Text = firstp.Link
-}
-
-func relinv(a obj.As) obj.As {
-       switch a {
-       case ABEQ:
-               return ABNE
-       case ABNE:
-               return ABEQ
-       case ABCS:
-               return ABCC
-       case ABHS:
-               return ABLO
-       case ABCC:
-               return ABCS
-       case ABLO:
-               return ABHS
-       case ABMI:
-               return ABPL
-       case ABPL:
-               return ABMI
-       case ABVS:
-               return ABVC
-       case ABVC:
-               return ABVS
-       case ABHI:
-               return ABLS
-       case ABLS:
-               return ABHI
-       case ABGE:
-               return ABLT
-       case ABLT:
-               return ABGE
-       case ABGT:
-               return ABLE
-       case ABLE:
-               return ABGT
-       case ACBZ:
-               return ACBNZ
-       case ACBNZ:
-               return ACBZ
-       case ACBZW:
-               return ACBNZW
-       case ACBNZW:
-               return ACBZW
-       }
-
-       log.Fatalf("unknown relation: %s", Anames[a-obj.ABaseARM64])
-       return 0
-}
-
-func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) {
-       var q *obj.Prog
-       var r *obj.Prog
-       var i int
-
-loop:
-       if p == nil {
-               return
-       }
-       a := p.As
-       if a == AB {
-               q = p.Pcond
-               if q != nil {
-                       p.Mark |= FOLL
-                       p = q
-                       if !(p.Mark&FOLL != 0) {
-                               goto loop
-                       }
-               }
-       }
-
-       if p.Mark&FOLL != 0 {
-               i = 0
-               q = p
-               for ; i < 4; i, q = i+1, q.Link {
-                       if q == *last || q == nil {
-                               break
-                       }
-                       a = q.As
-                       if a == obj.ANOP {
-                               i--
-                               continue
-                       }
-
-                       if a == AB || a == obj.ARET || a == AERET {
-                               goto copy
-                       }
-                       if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) {
-                               continue
-                       }
-                       if a != ABEQ && a != ABNE {
-                               continue
-                       }
-
-               copy:
-                       for {
-                               r = ctxt.NewProg()
-                               *r = *p
-                               if !(r.Mark&FOLL != 0) {
-                                       fmt.Printf("can't happen 1\n")
-                               }
-                               r.Mark |= FOLL
-                               if p != q {
-                                       p = p.Link
-                                       (*last).Link = r
-                                       *last = r
-                                       continue
-                               }
-
-                               (*last).Link = r
-                               *last = r
-                               if a == AB || a == obj.ARET || a == AERET {
-                                       return
-                               }
-                               if a == ABNE {
-                                       r.As = ABEQ
-                               } else {
-                                       r.As = ABNE
-                               }
-                               r.Pcond = p.Link
-                               r.Link = p.Pcond
-                               if !(r.Link.Mark&FOLL != 0) {
-                                       xfol(ctxt, r.Link, last)
-                               }
-                               if !(r.Pcond.Mark&FOLL != 0) {
-                                       fmt.Printf("can't happen 2\n")
-                               }
-                               return
-                       }
-               }
-
-               a = AB
-               q = ctxt.NewProg()
-               q.As = a
-               q.Pos = p.Pos
-               q.To.Type = obj.TYPE_BRANCH
-               q.To.Offset = p.Pc
-               q.Pcond = p
-               p = q
-       }
-
-       p.Mark |= FOLL
-       (*last).Link = p
-       *last = p
-       if a == AB || a == obj.ARET || a == AERET {
-               return
-       }
-       if p.Pcond != nil {
-               if a != ABL && p.Link != nil {
-                       q = obj.Brchain(ctxt, p.Link)
-                       if a != obj.ATEXT {
-                               if q != nil && (q.Mark&FOLL != 0) {
-                                       p.As = relinv(a)
-                                       p.Link = p.Pcond
-                                       p.Pcond = q
-                               }
-                       }
-
-                       xfol(ctxt, p.Link, last)
-                       q = obj.Brchain(ctxt, p.Pcond)
-                       if q == nil {
-                               q = p.Pcond
-                       }
-                       if q.Mark&FOLL != 0 {
-                               p.Pcond = q
-                               return
-                       }
-
-                       p = q
-                       goto loop
-               }
-       }
-
-       p = p.Link
-       goto loop
-}
-
 func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
        ctxt.Cursym = cursym
 
@@ -998,7 +812,6 @@ var Linkarm64 = obj.LinkArch{
        Arch:       sys.ArchARM64,
        Preprocess: preprocess,
        Assemble:   span7,
-       Follow:     follow,
        Progedit:   progedit,
        UnaryDst:   unaryDst,
 }
index ffc7a1b25b013e0ad6836d3036caec271e28038d..1d2d03593d391c2af00b8cae9a2ae03c7050cf51 100644 (file)
@@ -804,7 +804,6 @@ type LinkArch struct {
        *sys.Arch
        Preprocess func(*Link, *LSym)
        Assemble   func(*Link, *LSym)
-       Follow     func(*Link, *LSym)
        Progedit   func(*Link, *Prog)
        UnaryDst   map[As]bool // Instruction takes one operand, a destination.
 }
index 87ddcd2bb317deeec5db5b1515ec455a7c12e2fd..097b834e49410b6ea42be1aa35f86d0d0a2e7c67 100644 (file)
@@ -1418,151 +1418,10 @@ func compound(ctxt *obj.Link, p *obj.Prog) bool {
        return false
 }
 
-func follow(ctxt *obj.Link, s *obj.LSym) {
-       ctxt.Cursym = s
-
-       firstp := ctxt.NewProg()
-       lastp := firstp
-       xfol(ctxt, s.Text, &lastp)
-       lastp.Link = nil
-       s.Text = firstp.Link
-}
-
-func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) {
-       var q *obj.Prog
-       var r *obj.Prog
-       var i int
-
-loop:
-       if p == nil {
-               return
-       }
-       a := p.As
-       if a == AJMP {
-               q = p.Pcond
-               if (p.Mark&NOSCHED != 0) || q != nil && (q.Mark&NOSCHED != 0) {
-                       p.Mark |= FOLL
-                       (*last).Link = p
-                       *last = p
-                       p = p.Link
-                       xfol(ctxt, p, last)
-                       p = q
-                       if p != nil && p.Mark&FOLL == 0 {
-                               goto loop
-                       }
-                       return
-               }
-
-               if q != nil {
-                       p.Mark |= FOLL
-                       p = q
-                       if p.Mark&FOLL == 0 {
-                               goto loop
-                       }
-               }
-       }
-
-       if p.Mark&FOLL != 0 {
-               i = 0
-               q = p
-               for ; i < 4; i, q = i+1, q.Link {
-                       if q == *last || (q.Mark&NOSCHED != 0) {
-                               break
-                       }
-                       a = q.As
-                       if a == obj.ANOP {
-                               i--
-                               continue
-                       }
-
-                       if a == AJMP || a == ARET || a == ARFE {
-                               goto copy
-                       }
-                       if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) {
-                               continue
-                       }
-                       if a != ABEQ && a != ABNE {
-                               continue
-                       }
-
-               copy:
-                       for {
-                               r = ctxt.NewProg()
-                               *r = *p
-                               if r.Mark&FOLL == 0 {
-                                       fmt.Printf("can't happen 1\n")
-                               }
-                               r.Mark |= FOLL
-                               if p != q {
-                                       p = p.Link
-                                       (*last).Link = r
-                                       *last = r
-                                       continue
-                               }
-
-                               (*last).Link = r
-                               *last = r
-                               if a == AJMP || a == ARET || a == ARFE {
-                                       return
-                               }
-                               r.As = ABNE
-                               if a == ABNE {
-                                       r.As = ABEQ
-                               }
-                               r.Pcond = p.Link
-                               r.Link = p.Pcond
-                               if r.Link.Mark&FOLL == 0 {
-                                       xfol(ctxt, r.Link, last)
-                               }
-                               if r.Pcond.Mark&FOLL == 0 {
-                                       fmt.Printf("can't happen 2\n")
-                               }
-                               return
-                       }
-               }
-
-               a = AJMP
-               q = ctxt.NewProg()
-               q.As = a
-               q.Pos = p.Pos
-               q.To.Type = obj.TYPE_BRANCH
-               q.To.Offset = p.Pc
-               q.Pcond = p
-               p = q
-       }
-
-       p.Mark |= FOLL
-       (*last).Link = p
-       *last = p
-       if a == AJMP || a == ARET || a == ARFE {
-               if p.Mark&NOSCHED != 0 {
-                       p = p.Link
-                       goto loop
-               }
-
-               return
-       }
-
-       if p.Pcond != nil {
-               if a != AJAL && p.Link != nil {
-                       xfol(ctxt, p.Link, last)
-                       p = p.Pcond
-                       if p == nil || (p.Mark&FOLL != 0) {
-                               return
-                       }
-                       goto loop
-               }
-       }
-
-       p = p.Link
-       goto loop
-}
-
 var Linkmips64 = obj.LinkArch{
        Arch:       sys.ArchMIPS64,
        Preprocess: preprocess,
        Assemble:   span0,
-       Follow:     follow,
        Progedit:   progedit,
 }
 
@@ -1570,7 +1429,6 @@ var Linkmips64le = obj.LinkArch{
        Arch:       sys.ArchMIPS64LE,
        Preprocess: preprocess,
        Assemble:   span0,
-       Follow:     follow,
        Progedit:   progedit,
 }
 
@@ -1578,7 +1436,6 @@ var Linkmips = obj.LinkArch{
        Arch:       sys.ArchMIPS,
        Preprocess: preprocess,
        Assemble:   span0,
-       Follow:     follow,
        Progedit:   progedit,
 }
 
@@ -1586,6 +1443,5 @@ var Linkmipsle = obj.LinkArch{
        Arch:       sys.ArchMIPSLE,
        Preprocess: preprocess,
        Assemble:   span0,
-       Follow:     follow,
        Progedit:   progedit,
 }
index 804ea637b37b3983757eee7f342cec457d9792a4..643f9d02c05990d2bb852835eb54e71a369fa9dc 100644 (file)
@@ -159,9 +159,6 @@ func flushplist(ctxt *Link, freeProgs bool) {
        for _, s := range text {
                mkfwd(s)
                linkpatch(ctxt, s)
-               if ctxt.Flag_optimize {
-                       ctxt.Arch.Follow(ctxt, s)
-               }
                ctxt.Arch.Preprocess(ctxt, s)
                ctxt.Arch.Assemble(ctxt, s)
                fieldtrack(ctxt, s)
index b328781d8716cdce9779a7ba503e154dfe02fd00..7668ddd1fc7a81cafffa1ffa3315cb8d11634748 100644 (file)
@@ -1067,177 +1067,10 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
        return p
 }
 
-func follow(ctxt *obj.Link, s *obj.LSym) {
-       ctxt.Cursym = s
-
-       firstp := ctxt.NewProg()
-       lastp := firstp
-       xfol(ctxt, s.Text, &lastp)
-       lastp.Link = nil
-       s.Text = firstp.Link
-}
-
-func relinv(a obj.As) obj.As {
-       switch a {
-       case ABEQ:
-               return ABNE
-       case ABNE:
-               return ABEQ
-
-       case ABGE:
-               return ABLT
-       case ABLT:
-               return ABGE
-
-       case ABGT:
-               return ABLE
-       case ABLE:
-               return ABGT
-
-       case ABVC:
-               return ABVS
-       case ABVS:
-               return ABVC
-       }
-
-       return 0
-}
-
-func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) {
-       var q *obj.Prog
-       var r *obj.Prog
-       var b obj.As
-       var i int
-
-loop:
-       if p == nil {
-               return
-       }
-       a := p.As
-       if a == ABR {
-               q = p.Pcond
-               if (p.Mark&NOSCHED != 0) || q != nil && (q.Mark&NOSCHED != 0) {
-                       p.Mark |= FOLL
-                       (*last).Link = p
-                       *last = p
-                       p = p.Link
-                       xfol(ctxt, p, last)
-                       p = q
-                       if p != nil && p.Mark&FOLL == 0 {
-                               goto loop
-                       }
-                       return
-               }
-
-               if q != nil {
-                       p.Mark |= FOLL
-                       p = q
-                       if p.Mark&FOLL == 0 {
-                               goto loop
-                       }
-               }
-       }
-
-       if p.Mark&FOLL != 0 {
-               i = 0
-               q = p
-               for ; i < 4; i, q = i+1, q.Link {
-                       if q == *last || (q.Mark&NOSCHED != 0) {
-                               break
-                       }
-                       b = 0 /* set */
-                       a = q.As
-                       if a == obj.ANOP {
-                               i--
-                               continue
-                       }
-
-                       if a == ABR || a == obj.ARET || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID {
-                               goto copy
-                       }
-                       if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) {
-                               continue
-                       }
-                       b = relinv(a)
-                       if b == 0 {
-                               continue
-                       }
-
-               copy:
-                       for {
-                               r = ctxt.NewProg()
-                               *r = *p
-                               if r.Mark&FOLL == 0 {
-                                       fmt.Printf("can't happen 1\n")
-                               }
-                               r.Mark |= FOLL
-                               if p != q {
-                                       p = p.Link
-                                       (*last).Link = r
-                                       *last = r
-                                       continue
-                               }
-
-                               (*last).Link = r
-                               *last = r
-                               if a == ABR || a == obj.ARET || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID {
-                                       return
-                               }
-                               r.As = b
-                               r.Pcond = p.Link
-                               r.Link = p.Pcond
-                               if r.Link.Mark&FOLL == 0 {
-                                       xfol(ctxt, r.Link, last)
-                               }
-                               if r.Pcond.Mark&FOLL == 0 {
-                                       fmt.Printf("can't happen 2\n")
-                               }
-                               return
-                       }
-               }
-
-               a = ABR
-               q = ctxt.NewProg()
-               q.As = a
-               q.Pos = p.Pos
-               q.To.Type = obj.TYPE_BRANCH
-               q.To.Offset = p.Pc
-               q.Pcond = p
-               p = q
-       }
-
-       p.Mark |= FOLL
-       (*last).Link = p
-       *last = p
-       if a == ABR || a == obj.ARET || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID {
-               if p.Mark&NOSCHED != 0 {
-                       p = p.Link
-                       goto loop
-               }
-
-               return
-       }
-
-       if p.Pcond != nil {
-               if a != ABL && p.Link != nil {
-                       xfol(ctxt, p.Link, last)
-                       p = p.Pcond
-                       if p == nil || (p.Mark&FOLL != 0) {
-                               return
-                       }
-                       goto loop
-               }
-       }
-
-       p = p.Link
-       goto loop
-}
-
 var Linkppc64 = obj.LinkArch{
        Arch:       sys.ArchPPC64,
        Preprocess: preprocess,
        Assemble:   span9,
-       Follow:     follow,
        Progedit:   progedit,
 }
 
@@ -1245,6 +1078,5 @@ var Linkppc64le = obj.LinkArch{
        Arch:       sys.ArchPPC64LE,
        Preprocess: preprocess,
        Assemble:   span9,
-       Follow:     follow,
        Progedit:   progedit,
 }
index 86af775aad3ddc03ab2afb27314e341c10d9f121..9d2d931af12f36b3da480ddebc00fb13eb54a018 100644 (file)
@@ -837,176 +837,6 @@ func stacksplitPost(ctxt *obj.Link, p *obj.Prog, pPre *obj.Prog, pPreempt *obj.P
        return p
 }
 
-var pc_cnt int64
-
-func follow(ctxt *obj.Link, s *obj.LSym) {
-       ctxt.Cursym = s
-
-       pc_cnt = 0
-       firstp := ctxt.NewProg()
-       lastp := firstp
-       xfol(ctxt, s.Text, &lastp)
-       lastp.Link = nil
-       s.Text = firstp.Link
-}
-
-func relinv(a obj.As) obj.As {
-       switch a {
-       case ABEQ:
-               return ABNE
-       case ABNE:
-               return ABEQ
-
-       case ABGE:
-               return ABLT
-       case ABLT:
-               return ABGE
-
-       case ABGT:
-               return ABLE
-       case ABLE:
-               return ABGT
-
-       case ABVC:
-               return ABVS
-       case ABVS:
-               return ABVC
-       }
-
-       return 0
-}
-
-func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) {
-       var q *obj.Prog
-       var r *obj.Prog
-       var b obj.As
-
-       for p != nil {
-               a := p.As
-               if a == ABR {
-                       q = p.Pcond
-                       if (p.Mark&NOSCHED != 0) || q != nil && (q.Mark&NOSCHED != 0) {
-                               p.Mark |= FOLL
-                               (*last).Link = p
-                               *last = p
-                               (*last).Pc = pc_cnt
-                               pc_cnt += 1
-                               p = p.Link
-                               xfol(ctxt, p, last)
-                               p = q
-                               if p != nil && p.Mark&FOLL == 0 {
-                                       continue
-                               }
-                               return
-                       }
-
-                       if q != nil {
-                               p.Mark |= FOLL
-                               p = q
-                               if p.Mark&FOLL == 0 {
-                                       continue
-                               }
-                       }
-               }
-
-               if p.Mark&FOLL != 0 {
-                       q = p
-                       for i := 0; i < 4; i, q = i+1, q.Link {
-                               if q == *last || (q.Mark&NOSCHED != 0) {
-                                       break
-                               }
-                               b = 0 /* set */
-                               a = q.As
-                               if a == obj.ANOP {
-                                       i--
-                                       continue
-                               }
-                               if a != ABR && a != obj.ARET {
-                                       if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) {
-                                               continue
-                                       }
-                                       b = relinv(a)
-                                       if b == 0 {
-                                               continue
-                                       }
-                               }
-
-                               for {
-                                       r = ctxt.NewProg()
-                                       *r = *p
-                                       if r.Mark&FOLL == 0 {
-                                               fmt.Printf("can't happen 1\n")
-                                       }
-                                       r.Mark |= FOLL
-                                       if p != q {
-                                               p = p.Link
-                                               (*last).Link = r
-                                               *last = r
-                                               (*last).Pc = pc_cnt
-                                               pc_cnt += 1
-                                               continue
-                                       }
-
-                                       (*last).Link = r
-                                       *last = r
-                                       (*last).Pc = pc_cnt
-                                       pc_cnt += 1
-                                       if a == ABR || a == obj.ARET {
-                                               return
-                                       }
-                                       r.As = b
-                                       r.Pcond = p.Link
-                                       r.Link = p.Pcond
-                                       if r.Link.Mark&FOLL == 0 {
-                                               xfol(ctxt, r.Link, last)
-                                       }
-                                       if r.Pcond.Mark&FOLL == 0 {
-                                               fmt.Printf("can't happen 2\n")
-                                       }
-                                       return
-                               }
-                       }
-
-                       a = ABR
-                       q = ctxt.NewProg()
-                       q.As = a
-                       q.Pos = p.Pos
-                       q.To.Type = obj.TYPE_BRANCH
-                       q.To.Offset = p.Pc
-                       q.Pcond = p
-                       p = q
-               }
-
-               p.Mark |= FOLL
-               (*last).Link = p
-               *last = p
-               (*last).Pc = pc_cnt
-               pc_cnt += 1
-
-               if a == ABR || a == obj.ARET {
-                       if p.Mark&NOSCHED != 0 {
-                               p = p.Link
-                               continue
-                       }
-
-                       return
-               }
-
-               if p.Pcond != nil {
-                       if a != ABL && p.Link != nil {
-                               xfol(ctxt, p.Link, last)
-                               p = p.Pcond
-                               if p == nil || (p.Mark&FOLL != 0) {
-                                       return
-                               }
-                               continue
-                       }
-               }
-
-               p = p.Link
-       }
-}
-
 var unaryDst = map[obj.As]bool{
        ASTCK:  true,
        ASTCKC: true,
@@ -1022,7 +852,6 @@ var Links390x = obj.LinkArch{
        Arch:       sys.ArchS390X,
        Preprocess: preprocess,
        Assemble:   spanz,
-       Follow:     follow,
        Progedit:   progedit,
        UnaryDst:   unaryDst,
 }
index f1e2b2507d2e3aeae02d699fe4ad127d068683fc..ec73bb332774b001fa068016a4f9cea34ccd893d 100644 (file)
@@ -34,7 +34,6 @@ import (
        "cmd/internal/obj"
        "cmd/internal/sys"
        "fmt"
-       "log"
        "math"
        "strings"
 )
@@ -1183,241 +1182,6 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, textarg int32) *ob
        return jls
 }
 
-func follow(ctxt *obj.Link, s *obj.LSym) {
-       ctxt.Cursym = s
-
-       firstp := ctxt.NewProg()
-       lastp := firstp
-       xfol(ctxt, s.Text, &lastp)
-       lastp.Link = nil
-       s.Text = firstp.Link
-}
-
-func nofollow(a obj.As) bool {
-       switch a {
-       case obj.AJMP,
-               obj.ARET,
-               AIRETL,
-               AIRETQ,
-               AIRETW,
-               ARETFL,
-               ARETFQ,
-               ARETFW,
-               obj.AUNDEF:
-               return true
-       }
-
-       return false
-}
-
-func pushpop(a obj.As) bool {
-       switch a {
-       case APUSHL,
-               APUSHFL,
-               APUSHQ,
-               APUSHFQ,
-               APUSHW,
-               APUSHFW,
-               APOPL,
-               APOPFL,
-               APOPQ,
-               APOPFQ,
-               APOPW,
-               APOPFW:
-               return true
-       }
-
-       return false
-}
-
-func relinv(a obj.As) obj.As {
-       switch a {
-       case AJEQ:
-               return AJNE
-       case AJNE:
-               return AJEQ
-       case AJLE:
-               return AJGT
-       case AJLS:
-               return AJHI
-       case AJLT:
-               return AJGE
-       case AJMI:
-               return AJPL
-       case AJGE:
-               return AJLT
-       case AJPL:
-               return AJMI
-       case AJGT:
-               return AJLE
-       case AJHI:
-               return AJLS
-       case AJCS:
-               return AJCC
-       case AJCC:
-               return AJCS
-       case AJPS:
-               return AJPC
-       case AJPC:
-               return AJPS
-       case AJOS:
-               return AJOC
-       case AJOC:
-               return AJOS
-       }
-
-       log.Fatalf("unknown relation: %s", a)
-       return 0
-}
-
-func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) {
-       var q *obj.Prog
-       var i int
-       var a obj.As
-
-loop:
-       if p == nil {
-               return
-       }
-       if p.As == obj.AJMP {
-               q = p.Pcond
-               if q != nil && q.As != obj.ATEXT {
-                       /* mark instruction as done and continue layout at target of jump */
-                       p.Mark |= DONE
-
-                       p = q
-                       if p.Mark&DONE == 0 {
-                               goto loop
-                       }
-               }
-       }
-
-       if p.Mark&DONE != 0 {
-               /*
-                * p goes here, but already used it elsewhere.
-                * copy up to 4 instructions or else branch to other copy.
-                */
-               i = 0
-               q = p
-               for ; i < 4; i, q = i+1, q.Link {
-                       if q == nil {
-                               break
-                       }
-                       if q == *last {
-                               break
-                       }
-                       a = q.As
-                       if a == obj.ANOP {
-                               i--
-                               continue
-                       }
-
-                       if nofollow(a) || pushpop(a) {
-                               break // NOTE(rsc): arm does goto copy
-                       }
-                       if q.Pcond == nil || q.Pcond.Mark&DONE != 0 {
-                               continue
-                       }
-                       if a == obj.ACALL || a == ALOOP {
-                               continue
-                       }
-                       for {
-                               if p.As == obj.ANOP {
-                                       p = p.Link
-                                       continue
-                               }
-
-                               q = obj.Copyp(ctxt, p)
-                               p = p.Link
-                               q.Mark |= DONE
-                               (*last).Link = q
-                               *last = q
-                               if q.As != a || q.Pcond == nil || q.Pcond.Mark&DONE != 0 {
-                                       continue
-                               }
-
-                               q.As = relinv(q.As)
-                               p = q.Pcond
-                               q.Pcond = q.Link
-                               q.Link = p
-                               xfol(ctxt, q.Link, last)
-                               p = q.Link
-                               if p.Mark&DONE != 0 {
-                                       return
-                               }
-                               goto loop
-                               /* */
-                       }
-               }
-               q = ctxt.NewProg()
-               q.As = obj.AJMP
-               q.Pos = p.Pos
-               q.To.Type = obj.TYPE_BRANCH
-               q.To.Offset = p.Pc
-               q.Pcond = p
-               p = q
-       }
-
-       /* emit p */
-       p.Mark |= DONE
-
-       (*last).Link = p
-       *last = p
-       a = p.As
-
-       /* continue loop with what comes after p */
-       if nofollow(a) {
-               return
-       }
-       if p.Pcond != nil && a != obj.ACALL {
-               /*
-                * some kind of conditional branch.
-                * recurse to follow one path.
-                * continue loop on the other.
-                */
-               q = obj.Brchain(ctxt, p.Pcond)
-               if q != nil {
-                       p.Pcond = q
-               }
-               q = obj.Brchain(ctxt, p.Link)
-               if q != nil {
-                       p.Link = q
-               }
-               if p.From.Type == obj.TYPE_CONST {
-                       if p.From.Offset == 1 {
-                               /*
-                                * expect conditional jump to be taken.
-                                * rewrite so that's the fall-through case.
-                                */
-                               p.As = relinv(a)
-
-                               q = p.Link
-                               p.Link = p.Pcond
-                               p.Pcond = q
-                       }
-               } else {
-                       q = p.Link
-                       if q.Mark&DONE != 0 {
-                               if a != ALOOP {
-                                       p.As = relinv(a)
-                                       p.Link = p.Pcond
-                                       p.Pcond = q
-                               }
-                       }
-               }
-
-               xfol(ctxt, p.Link, last)
-               if p.Pcond.Mark&DONE != 0 {
-                       return
-               }
-               p = p.Pcond
-               goto loop
-       }
-
-       p = p.Link
-       goto loop
-}
-
 var unaryDst = map[obj.As]bool{
        ABSWAPL:    true,
        ABSWAPQ:    true,
@@ -1472,7 +1236,6 @@ var Linkamd64 = obj.LinkArch{
        Arch:       sys.ArchAMD64,
        Preprocess: preprocess,
        Assemble:   span6,
-       Follow:     follow,
        Progedit:   progedit,
        UnaryDst:   unaryDst,
 }
@@ -1481,7 +1244,6 @@ var Linkamd64p32 = obj.LinkArch{
        Arch:       sys.ArchAMD64P32,
        Preprocess: preprocess,
        Assemble:   span6,
-       Follow:     follow,
        Progedit:   progedit,
        UnaryDst:   unaryDst,
 }
@@ -1490,7 +1252,6 @@ var Link386 = obj.LinkArch{
        Arch:       sys.Arch386,
        Preprocess: preprocess,
        Assemble:   span6,
-       Follow:     follow,
        Progedit:   progedit,
        UnaryDst:   unaryDst,
 }
index db07ae51fd095330732b54a8ad70554220e930b5..8ec551062505ff3831fa1940e2caf3bf6cd7cf84 100644 (file)
@@ -366,40 +366,40 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$80
        // 136(SI) is saved EFLAGS, never to be seen again
        JMP     SI
 
-debughandler:
-       // print basic information
-       LEAL    ctxt+0(FP), DI
-       MOVL    $runtime·sigtrampf(SB), AX
-       MOVL    AX, 0(SP)
-       MOVQ    (16*4+16*8)(DI), BX // rip
-       MOVQ    BX, 8(SP)
-       MOVQ    (16*4+0*8)(DI), BX // rax
-       MOVQ    BX, 16(SP)
-       MOVQ    (16*4+1*8)(DI), BX // rcx
-       MOVQ    BX, 24(SP)
-       MOVQ    (16*4+2*8)(DI), BX // rdx
-       MOVQ    BX, 32(SP)
-       MOVQ    (16*4+3*8)(DI), BX // rbx
-       MOVQ    BX, 40(SP)
-       MOVQ    (16*4+7*8)(DI), BX // rdi
-       MOVQ    BX, 48(SP)
-       MOVQ    (16*4+15*8)(DI), BX // r15
-       MOVQ    BX, 56(SP)
-       MOVQ    (16*4+4*8)(DI), BX // rsp
-       MOVQ    0(BX), BX
-       MOVQ    BX, 64(SP)
-       CALL    runtime·printf(SB)
-       
-       LEAL    ctxt+0(FP), DI
-       MOVQ    (16*4+16*8)(DI), BX // rip
-       MOVL    BX, 0(SP)
-       MOVQ    (16*4+4*8)(DI), BX // rsp
-       MOVL    BX, 4(SP)
-       MOVL    $0, 8(SP)       // lr
-       get_tls(CX)
-       MOVL    g(CX), BX
-       MOVL    BX, 12(SP)      // gp
-       CALL    runtime·traceback(SB)
+//debughandler:
+       //// print basic information
+       //LEAL  ctxt+0(FP), DI
+       //MOVL  $runtime·sigtrampf(SB), AX
+       //MOVL  AX, 0(SP)
+       //MOVQ  (16*4+16*8)(DI), BX // rip
+       //MOVQ  BX, 8(SP)
+       //MOVQ  (16*4+0*8)(DI), BX // rax
+       //MOVQ  BX, 16(SP)
+       //MOVQ  (16*4+1*8)(DI), BX // rcx
+       //MOVQ  BX, 24(SP)
+       //MOVQ  (16*4+2*8)(DI), BX // rdx
+       //MOVQ  BX, 32(SP)
+       //MOVQ  (16*4+3*8)(DI), BX // rbx
+       //MOVQ  BX, 40(SP)
+       //MOVQ  (16*4+7*8)(DI), BX // rdi
+       //MOVQ  BX, 48(SP)
+       //MOVQ  (16*4+15*8)(DI), BX // r15
+       //MOVQ  BX, 56(SP)
+       //MOVQ  (16*4+4*8)(DI), BX // rsp
+       //MOVQ  0(BX), BX
+       //MOVQ  BX, 64(SP)
+       //CALL  runtime·printf(SB)
+       //
+       //LEAL  ctxt+0(FP), DI
+       //MOVQ  (16*4+16*8)(DI), BX // rip
+       //MOVL  BX, 0(SP)
+       //MOVQ  (16*4+4*8)(DI), BX // rsp
+       //MOVL  BX, 4(SP)
+       //MOVL  $0, 8(SP)       // lr
+       //get_tls(CX)
+       //MOVL  g(CX), BX
+       //MOVL  BX, 12(SP)      // gp
+       //CALL  runtime·traceback(SB)
 
 notls:
        MOVL    0, AX