1
2
3
4
5 package ssa
6
7 import (
8 "cmd/compile/internal/types"
9 "cmd/internal/obj"
10 "cmd/internal/objabi"
11 "cmd/internal/src"
12 )
13
14
15
16
17 type Config struct {
18 arch string
19 PtrSize int64
20 RegSize int64
21 Types Types
22 lowerBlock blockRewriter
23 lowerValue valueRewriter
24 splitLoad valueRewriter
25 registers []Register
26 gpRegMask regMask
27 fpRegMask regMask
28 fp32RegMask regMask
29 fp64RegMask regMask
30 specialRegMask regMask
31 GCRegMap []*Register
32 FPReg int8
33 LinkReg int8
34 hasGReg bool
35 ctxt *obj.Link
36 optimize bool
37 noDuffDevice bool
38 useSSE bool
39 useAvg bool
40 useHmul bool
41 SoftFloat bool
42 Race bool
43 NeedsFpScratch bool
44 BigEndian bool
45 UseFMA bool
46 }
47
48 type (
49 blockRewriter func(*Block) bool
50 valueRewriter func(*Value) bool
51 )
52
53 type Types struct {
54 Bool *types.Type
55 Int8 *types.Type
56 Int16 *types.Type
57 Int32 *types.Type
58 Int64 *types.Type
59 UInt8 *types.Type
60 UInt16 *types.Type
61 UInt32 *types.Type
62 UInt64 *types.Type
63 Int *types.Type
64 Float32 *types.Type
65 Float64 *types.Type
66 UInt *types.Type
67 Uintptr *types.Type
68 String *types.Type
69 BytePtr *types.Type
70 Int32Ptr *types.Type
71 UInt32Ptr *types.Type
72 IntPtr *types.Type
73 UintptrPtr *types.Type
74 Float32Ptr *types.Type
75 Float64Ptr *types.Type
76 BytePtrPtr *types.Type
77 }
78
79
80 func NewTypes() *Types {
81 t := new(Types)
82 t.SetTypPtrs()
83 return t
84 }
85
86
87 func (t *Types) SetTypPtrs() {
88 t.Bool = types.Types[types.TBOOL]
89 t.Int8 = types.Types[types.TINT8]
90 t.Int16 = types.Types[types.TINT16]
91 t.Int32 = types.Types[types.TINT32]
92 t.Int64 = types.Types[types.TINT64]
93 t.UInt8 = types.Types[types.TUINT8]
94 t.UInt16 = types.Types[types.TUINT16]
95 t.UInt32 = types.Types[types.TUINT32]
96 t.UInt64 = types.Types[types.TUINT64]
97 t.Int = types.Types[types.TINT]
98 t.Float32 = types.Types[types.TFLOAT32]
99 t.Float64 = types.Types[types.TFLOAT64]
100 t.UInt = types.Types[types.TUINT]
101 t.Uintptr = types.Types[types.TUINTPTR]
102 t.String = types.Types[types.TSTRING]
103 t.BytePtr = types.NewPtr(types.Types[types.TUINT8])
104 t.Int32Ptr = types.NewPtr(types.Types[types.TINT32])
105 t.UInt32Ptr = types.NewPtr(types.Types[types.TUINT32])
106 t.IntPtr = types.NewPtr(types.Types[types.TINT])
107 t.UintptrPtr = types.NewPtr(types.Types[types.TUINTPTR])
108 t.Float32Ptr = types.NewPtr(types.Types[types.TFLOAT32])
109 t.Float64Ptr = types.NewPtr(types.Types[types.TFLOAT64])
110 t.BytePtrPtr = types.NewPtr(types.NewPtr(types.Types[types.TUINT8]))
111 }
112
113 type Logger interface {
114
115 Logf(string, ...interface{})
116
117
118
119 Log() bool
120
121
122 Fatalf(pos src.XPos, msg string, args ...interface{})
123
124
125 Warnl(pos src.XPos, fmt_ string, args ...interface{})
126
127
128 Debug_checknil() bool
129 }
130
131 type Frontend interface {
132 CanSSA(t *types.Type) bool
133
134 Logger
135
136
137 StringData(string) *obj.LSym
138
139
140
141 Auto(src.XPos, *types.Type) GCNode
142
143
144
145 SplitString(LocalSlot) (LocalSlot, LocalSlot)
146 SplitInterface(LocalSlot) (LocalSlot, LocalSlot)
147 SplitSlice(LocalSlot) (LocalSlot, LocalSlot, LocalSlot)
148 SplitComplex(LocalSlot) (LocalSlot, LocalSlot)
149 SplitStruct(LocalSlot, int) LocalSlot
150 SplitArray(LocalSlot) LocalSlot
151 SplitInt64(LocalSlot) (LocalSlot, LocalSlot)
152 SplitSlot(parent *LocalSlot, suffix string, offset int64, t *types.Type) LocalSlot
153
154
155
156
157
158 DerefItab(sym *obj.LSym, offset int64) *obj.LSym
159
160
161 Line(src.XPos) string
162
163
164 AllocFrame(f *Func)
165
166
167
168 Syslook(string) *obj.LSym
169
170
171 UseWriteBarrier() bool
172
173
174
175 SetWBPos(pos src.XPos)
176
177
178 MyImportPath() string
179 }
180
181
182
183 type GCNode interface {
184 Typ() *types.Type
185 String() string
186 IsSynthetic() bool
187 IsAutoTmp() bool
188 StorageClass() StorageClass
189 }
190
191 type StorageClass uint8
192
193 const (
194 ClassAuto StorageClass = iota
195 ClassParam
196 ClassParamOut
197 )
198
199 const go116lateCallExpansion = true
200
201
202
203 func LateCallExpansionEnabledWithin(f *Func) bool {
204 return go116lateCallExpansion
205 }
206
207
208 func NewConfig(arch string, types Types, ctxt *obj.Link, optimize bool) *Config {
209 c := &Config{arch: arch, Types: types}
210 c.useAvg = true
211 c.useHmul = true
212 switch arch {
213 case "amd64":
214 c.PtrSize = 8
215 c.RegSize = 8
216 c.lowerBlock = rewriteBlockAMD64
217 c.lowerValue = rewriteValueAMD64
218 c.splitLoad = rewriteValueAMD64splitload
219 c.registers = registersAMD64[:]
220 c.gpRegMask = gpRegMaskAMD64
221 c.fpRegMask = fpRegMaskAMD64
222 c.FPReg = framepointerRegAMD64
223 c.LinkReg = linkRegAMD64
224 c.hasGReg = false
225 case "386":
226 c.PtrSize = 4
227 c.RegSize = 4
228 c.lowerBlock = rewriteBlock386
229 c.lowerValue = rewriteValue386
230 c.splitLoad = rewriteValue386splitload
231 c.registers = registers386[:]
232 c.gpRegMask = gpRegMask386
233 c.fpRegMask = fpRegMask386
234 c.FPReg = framepointerReg386
235 c.LinkReg = linkReg386
236 c.hasGReg = false
237 case "arm":
238 c.PtrSize = 4
239 c.RegSize = 4
240 c.lowerBlock = rewriteBlockARM
241 c.lowerValue = rewriteValueARM
242 c.registers = registersARM[:]
243 c.gpRegMask = gpRegMaskARM
244 c.fpRegMask = fpRegMaskARM
245 c.FPReg = framepointerRegARM
246 c.LinkReg = linkRegARM
247 c.hasGReg = true
248 case "arm64":
249 c.PtrSize = 8
250 c.RegSize = 8
251 c.lowerBlock = rewriteBlockARM64
252 c.lowerValue = rewriteValueARM64
253 c.registers = registersARM64[:]
254 c.gpRegMask = gpRegMaskARM64
255 c.fpRegMask = fpRegMaskARM64
256 c.FPReg = framepointerRegARM64
257 c.LinkReg = linkRegARM64
258 c.hasGReg = true
259 c.noDuffDevice = objabi.GOOS == "darwin" || objabi.GOOS == "ios"
260 case "ppc64":
261 c.BigEndian = true
262 fallthrough
263 case "ppc64le":
264 c.PtrSize = 8
265 c.RegSize = 8
266 c.lowerBlock = rewriteBlockPPC64
267 c.lowerValue = rewriteValuePPC64
268 c.registers = registersPPC64[:]
269 c.gpRegMask = gpRegMaskPPC64
270 c.fpRegMask = fpRegMaskPPC64
271 c.FPReg = framepointerRegPPC64
272 c.LinkReg = linkRegPPC64
273 c.noDuffDevice = true
274 c.hasGReg = true
275 case "mips64":
276 c.BigEndian = true
277 fallthrough
278 case "mips64le":
279 c.PtrSize = 8
280 c.RegSize = 8
281 c.lowerBlock = rewriteBlockMIPS64
282 c.lowerValue = rewriteValueMIPS64
283 c.registers = registersMIPS64[:]
284 c.gpRegMask = gpRegMaskMIPS64
285 c.fpRegMask = fpRegMaskMIPS64
286 c.specialRegMask = specialRegMaskMIPS64
287 c.FPReg = framepointerRegMIPS64
288 c.LinkReg = linkRegMIPS64
289 c.hasGReg = true
290 case "s390x":
291 c.PtrSize = 8
292 c.RegSize = 8
293 c.lowerBlock = rewriteBlockS390X
294 c.lowerValue = rewriteValueS390X
295 c.registers = registersS390X[:]
296 c.gpRegMask = gpRegMaskS390X
297 c.fpRegMask = fpRegMaskS390X
298 c.FPReg = framepointerRegS390X
299 c.LinkReg = linkRegS390X
300 c.hasGReg = true
301 c.noDuffDevice = true
302 c.BigEndian = true
303 case "mips":
304 c.BigEndian = true
305 fallthrough
306 case "mipsle":
307 c.PtrSize = 4
308 c.RegSize = 4
309 c.lowerBlock = rewriteBlockMIPS
310 c.lowerValue = rewriteValueMIPS
311 c.registers = registersMIPS[:]
312 c.gpRegMask = gpRegMaskMIPS
313 c.fpRegMask = fpRegMaskMIPS
314 c.specialRegMask = specialRegMaskMIPS
315 c.FPReg = framepointerRegMIPS
316 c.LinkReg = linkRegMIPS
317 c.hasGReg = true
318 c.noDuffDevice = true
319 case "riscv64":
320 c.PtrSize = 8
321 c.RegSize = 8
322 c.lowerBlock = rewriteBlockRISCV64
323 c.lowerValue = rewriteValueRISCV64
324 c.registers = registersRISCV64[:]
325 c.gpRegMask = gpRegMaskRISCV64
326 c.fpRegMask = fpRegMaskRISCV64
327 c.FPReg = framepointerRegRISCV64
328 c.hasGReg = true
329 case "wasm":
330 c.PtrSize = 8
331 c.RegSize = 8
332 c.lowerBlock = rewriteBlockWasm
333 c.lowerValue = rewriteValueWasm
334 c.registers = registersWasm[:]
335 c.gpRegMask = gpRegMaskWasm
336 c.fpRegMask = fpRegMaskWasm
337 c.fp32RegMask = fp32RegMaskWasm
338 c.fp64RegMask = fp64RegMaskWasm
339 c.FPReg = framepointerRegWasm
340 c.LinkReg = linkRegWasm
341 c.hasGReg = true
342 c.noDuffDevice = true
343 c.useAvg = false
344 c.useHmul = false
345 default:
346 ctxt.Diag("arch %s not implemented", arch)
347 }
348 c.ctxt = ctxt
349 c.optimize = optimize
350 c.useSSE = true
351 c.UseFMA = true
352
353
354 if objabi.GOOS == "plan9" {
355
356 c.UseFMA = false
357
358
359 if arch == "amd64" {
360 c.noDuffDevice = true
361 c.useSSE = false
362 }
363 }
364
365 if ctxt.Flag_shared {
366
367
368
369 opcodeTable[Op386LoweredWB].reg.clobbers |= 1 << 3
370 }
371
372
373
374 gcRegMapSize := int16(0)
375 for _, r := range c.registers {
376 if r.gcNum+1 > gcRegMapSize {
377 gcRegMapSize = r.gcNum + 1
378 }
379 }
380 c.GCRegMap = make([]*Register, gcRegMapSize)
381 for i, r := range c.registers {
382 if r.gcNum != -1 {
383 c.GCRegMap[r.gcNum] = &c.registers[i]
384 }
385 }
386
387 return c
388 }
389
390 func (c *Config) Ctxt() *obj.Link { return c.ctxt }
391
View as plain text