Source file src/pkg/cmd/compile/internal/gc/gsubr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 package gc
32
33 import (
34 "cmd/compile/internal/ssa"
35 "cmd/compile/internal/types"
36 "cmd/internal/obj"
37 "cmd/internal/objabi"
38 "cmd/internal/src"
39 )
40
41 var sharedProgArray = new([10000]obj.Prog)
42
43
44 type Progs struct {
45 Text *obj.Prog
46 next *obj.Prog
47 pc int64
48 pos src.XPos
49 curfn *Node
50 progcache []obj.Prog
51 cacheidx int
52
53 nextLive LivenessIndex
54 prevLive LivenessIndex
55 }
56
57
58
59 func newProgs(fn *Node, worker int) *Progs {
60 pp := new(Progs)
61 if Ctxt.CanReuseProgs() {
62 sz := len(sharedProgArray) / nBackendWorkers
63 pp.progcache = sharedProgArray[sz*worker : sz*(worker+1)]
64 }
65 pp.curfn = fn
66
67
68 pp.next = pp.NewProg()
69 pp.clearp(pp.next)
70
71 pp.pos = fn.Pos
72 pp.settext(fn)
73 pp.nextLive = LivenessInvalid
74 pp.prevLive = LivenessInvalid
75 return pp
76 }
77
78 func (pp *Progs) NewProg() *obj.Prog {
79 var p *obj.Prog
80 if pp.cacheidx < len(pp.progcache) {
81 p = &pp.progcache[pp.cacheidx]
82 pp.cacheidx++
83 } else {
84 p = new(obj.Prog)
85 }
86 p.Ctxt = Ctxt
87 return p
88 }
89
90
91 func (pp *Progs) Flush() {
92 plist := &obj.Plist{Firstpc: pp.Text, Curfn: pp.curfn}
93 obj.Flushplist(Ctxt, plist, pp.NewProg, myimportpath)
94 }
95
96
97 func (pp *Progs) Free() {
98 if Ctxt.CanReuseProgs() {
99
100 s := pp.progcache[:pp.cacheidx]
101 for i := range s {
102 s[i] = obj.Prog{}
103 }
104 }
105
106 *pp = Progs{}
107 }
108
109
110 func (pp *Progs) Prog(as obj.As) *obj.Prog {
111 if pp.nextLive.stackMapIndex != pp.prevLive.stackMapIndex {
112
113 idx := pp.nextLive.stackMapIndex
114 pp.prevLive.stackMapIndex = idx
115 p := pp.Prog(obj.APCDATA)
116 Addrconst(&p.From, objabi.PCDATA_StackMapIndex)
117 Addrconst(&p.To, int64(idx))
118 }
119 if pp.nextLive.regMapIndex != pp.prevLive.regMapIndex {
120
121 idx := pp.nextLive.regMapIndex
122 pp.prevLive.regMapIndex = idx
123 p := pp.Prog(obj.APCDATA)
124 Addrconst(&p.From, objabi.PCDATA_RegMapIndex)
125 Addrconst(&p.To, int64(idx))
126 }
127
128 p := pp.next
129 pp.next = pp.NewProg()
130 pp.clearp(pp.next)
131 p.Link = pp.next
132
133 if !pp.pos.IsKnown() && Debug['K'] != 0 {
134 Warn("prog: unknown position (line 0)")
135 }
136
137 p.As = as
138 p.Pos = pp.pos
139 if pp.pos.IsStmt() == src.PosIsStmt {
140
141 if ssa.LosesStmtMark(as) {
142 return p
143 }
144 pp.pos = pp.pos.WithNotStmt()
145 }
146 return p
147 }
148
149 func (pp *Progs) clearp(p *obj.Prog) {
150 obj.Nopout(p)
151 p.As = obj.AEND
152 p.Pc = pp.pc
153 pp.pc++
154 }
155
156 func (pp *Progs) Appendpp(p *obj.Prog, as obj.As, ftype obj.AddrType, freg int16, foffset int64, ttype obj.AddrType, treg int16, toffset int64) *obj.Prog {
157 q := pp.NewProg()
158 pp.clearp(q)
159 q.As = as
160 q.Pos = p.Pos
161 q.From.Type = ftype
162 q.From.Reg = freg
163 q.From.Offset = foffset
164 q.To.Type = ttype
165 q.To.Reg = treg
166 q.To.Offset = toffset
167 q.Link = p.Link
168 p.Link = q
169 return q
170 }
171
172 func (pp *Progs) settext(fn *Node) {
173 if pp.Text != nil {
174 Fatalf("Progs.settext called twice")
175 }
176 ptxt := pp.Prog(obj.ATEXT)
177 pp.Text = ptxt
178
179 fn.Func.lsym.Func.Text = ptxt
180 ptxt.From.Type = obj.TYPE_MEM
181 ptxt.From.Name = obj.NAME_EXTERN
182 ptxt.From.Sym = fn.Func.lsym
183 }
184
185
186
187
188
189
190
191 func (f *Func) initLSym(hasBody bool) {
192 if f.lsym != nil {
193 Fatalf("Func.initLSym called twice")
194 }
195
196 if nam := f.Nname; !nam.isBlank() {
197 f.lsym = nam.Sym.Linksym()
198 if f.Pragma&Systemstack != 0 {
199 f.lsym.Set(obj.AttrCFunc, true)
200 }
201
202 var aliasABI obj.ABI
203 needABIAlias := false
204 defABI, hasDefABI := symabiDefs[f.lsym.Name]
205 if hasDefABI && defABI == obj.ABI0 {
206
207
208 f.lsym.SetABI(obj.ABI0)
209 needABIAlias, aliasABI = true, obj.ABIInternal
210 } else {
211
212
213 want := obj.ABIInternal
214 if f.lsym.ABI() != want {
215 Fatalf("function symbol %s has the wrong ABI %v, expected %v", f.lsym.Name, f.lsym.ABI(), want)
216 }
217 }
218
219 isLinknameExported := nam.Sym.Linkname != "" && (hasBody || hasDefABI)
220 if abi, ok := symabiRefs[f.lsym.Name]; (ok && abi == obj.ABI0) || isLinknameExported {
221
222
223
224
225
226
227
228
229
230
231
232 if f.lsym.ABI() != obj.ABI0 {
233 needABIAlias, aliasABI = true, obj.ABI0
234 }
235 }
236
237 if needABIAlias {
238
239
240
241
242 asym := &obj.LSym{
243 Name: f.lsym.Name,
244 Type: objabi.SABIALIAS,
245 R: []obj.Reloc{{Sym: f.lsym}},
246 }
247 asym.SetABI(aliasABI)
248 asym.Set(obj.AttrDuplicateOK, true)
249 Ctxt.ABIAliases = append(Ctxt.ABIAliases, asym)
250 }
251 }
252
253 if !hasBody {
254
255 return
256 }
257
258 var flag int
259 if f.Dupok() {
260 flag |= obj.DUPOK
261 }
262 if f.Wrapper() {
263 flag |= obj.WRAPPER
264 }
265 if f.Needctxt() {
266 flag |= obj.NEEDCTXT
267 }
268 if f.Pragma&Nosplit != 0 {
269 flag |= obj.NOSPLIT
270 }
271 if f.ReflectMethod() {
272 flag |= obj.REFLECTMETHOD
273 }
274
275
276
277
278 if myimportpath == "reflect" {
279 switch f.Nname.Sym.Name {
280 case "callReflect", "callMethod":
281 flag |= obj.WRAPPER
282 }
283 }
284
285 Ctxt.InitTextSym(f.lsym, flag)
286 }
287
288 func ggloblnod(nam *Node) {
289 s := nam.Sym.Linksym()
290 s.Gotype = ngotype(nam).Linksym()
291 flags := 0
292 if nam.Name.Readonly() {
293 flags = obj.RODATA
294 }
295 if nam.Type != nil && !types.Haspointers(nam.Type) {
296 flags |= obj.NOPTR
297 }
298 Ctxt.Globl(s, nam.Type.Width, flags)
299 }
300
301 func ggloblsym(s *obj.LSym, width int32, flags int16) {
302 if flags&obj.LOCAL != 0 {
303 s.Set(obj.AttrLocal, true)
304 flags &^= obj.LOCAL
305 }
306 Ctxt.Globl(s, int64(width), int(flags))
307 }
308
309 func isfat(t *types.Type) bool {
310 if t != nil {
311 switch t.Etype {
312 case TSTRUCT, TARRAY, TSLICE, TSTRING,
313 TINTER:
314 return true
315 }
316 }
317
318 return false
319 }
320
321 func Addrconst(a *obj.Addr, v int64) {
322 a.Sym = nil
323 a.Type = obj.TYPE_CONST
324 a.Offset = v
325 }
326
327 func Patch(p *obj.Prog, to *obj.Prog) {
328 if p.To.Type != obj.TYPE_BRANCH {
329 Fatalf("patch: not a branch")
330 }
331 p.To.Val = to
332 p.To.Offset = to.Pc
333 }
334
View as plain text