github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/cmd/internal/obj/sparc64/vn.go (about) 1 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 2 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 3 // Portions Copyright © 1997-1999 Vita Nuova Limited 4 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 5 // Portions Copyright © 2004,2006 Bruce Ellis 6 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 7 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 8 // Portions Copyright © 2009 The Go Authors. All rights reserved. 9 // 10 // Permission is hereby granted, free of charge, to any person obtaining a copy 11 // of this software and associated documentation files (the "Software"), to deal 12 // in the Software without restriction, including without limitation the rights 13 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 // copies of the Software, and to permit persons to whom the Software is 15 // furnished to do so, subject to the following conditions: 16 // 17 // The above copyright notice and this permission notice shall be included in 18 // all copies or substantial portions of the Software. 19 // 20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 // THE SOFTWARE. 27 28 // Unlike all existing ports (386, amd64, amd64p32, arm, arm64, ppc64, 29 // ppc64le), the sparc64 back-end is truly new code, not derived from 30 // Plan9/Inferno code from Vita Nuova. However, the sparc64 back-end 31 // has to fit into the Inferno-derived middle-end (cmd/internal/obj), 32 // and inherits certain idiosyncrasies. To deal with them, a small 33 // amount of code is inherited from the arm64 port. To track copyrights, 34 // that code is isolated in this file. 35 // 36 // Someday we'll refactor the middle-end, and this code will go away. 37 38 package sparc64 39 40 import ( 41 "cmd/internal/obj" 42 "fmt" 43 ) 44 45 func follow(ctxt *obj.Link, s *obj.LSym) { 46 ctxt.Cursym = s 47 48 firstp := ctxt.NewProg() 49 lastp := firstp 50 xfol(ctxt, s.Text, &lastp) 51 lastp.Link = nil 52 s.Text = firstp.Link 53 } 54 55 func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) { 56 var q *obj.Prog 57 var r *obj.Prog 58 var a obj.As 59 var i int 60 61 loop: 62 if p == nil { 63 return 64 } 65 a = p.As 66 if a == obj.AJMP { 67 q = p.Pcond 68 if q != nil { 69 p.Mark |= FOLL 70 p = q 71 if !(p.Mark&FOLL != 0) { 72 goto loop 73 } 74 } 75 } 76 77 if p.Mark&FOLL != 0 { 78 i = 0 79 q = p 80 for ; i < 4; i, q = i+1, q.Link { 81 if q == *last || q == nil { 82 break 83 } 84 a = q.As 85 if a == obj.ANOP { 86 i-- 87 continue 88 } 89 90 if a == obj.AJMP || a == obj.ARET || a == ARETRESTORE { 91 goto copy 92 } 93 if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) { 94 continue 95 } 96 if a != ABE && a != ABNE { 97 continue 98 } 99 100 copy: 101 for { 102 r = ctxt.NewProg() 103 *r = *p 104 if !(r.Mark&FOLL != 0) { 105 fmt.Printf("cant happen 1\n") 106 } 107 r.Mark |= FOLL 108 if p != q { 109 p = p.Link 110 (*last).Link = r 111 *last = r 112 continue 113 } 114 115 (*last).Link = r 116 *last = r 117 if a == obj.AJMP || a == obj.ARET || a == ARETRESTORE { 118 return 119 } 120 if a == ABNE { 121 r.As = ABE 122 } else { 123 r.As = ABNE 124 } 125 r.Pcond = p.Link 126 r.Link = p.Pcond 127 if !(r.Link.Mark&FOLL != 0) { 128 xfol(ctxt, r.Link, last) 129 } 130 if !(r.Pcond.Mark&FOLL != 0) { 131 fmt.Printf("cant happen 2\n") 132 } 133 return 134 } 135 } 136 137 a = obj.AJMP 138 q = ctxt.NewProg() 139 q.As = a 140 q.Lineno = p.Lineno 141 q.To.Type = obj.TYPE_BRANCH 142 q.To.Offset = p.Pc 143 q.Pcond = p 144 p = q 145 } 146 147 p.Mark |= FOLL 148 (*last).Link = p 149 *last = p 150 if a == obj.AJMP || a == obj.ARET || a == ARETRESTORE { 151 return 152 } 153 if p.Pcond != nil { 154 if a != ABL && p.Link != nil { 155 q = obj.Brchain(ctxt, p.Link) 156 if a != obj.ATEXT { 157 if q != nil && (q.Mark&FOLL != 0) { 158 p.As = relinv(a) 159 p.Link = p.Pcond 160 p.Pcond = q 161 } 162 } 163 164 xfol(ctxt, p.Link, last) 165 q = obj.Brchain(ctxt, p.Pcond) 166 if q == nil { 167 q = p.Pcond 168 } 169 if q.Mark&FOLL != 0 { 170 p.Pcond = q 171 return 172 } 173 174 p = q 175 goto loop 176 } 177 } 178 179 p = p.Link 180 goto loop 181 182 }