...
Source file src/pkg/cmd/compile/internal/ssa/config.go
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 specialRegMask regMask
29 GCRegMap []*Register
30 FPReg int8
31 LinkReg int8
32 hasGReg bool
33 ctxt *obj.Link
34 optimize bool
35 noDuffDevice bool
36 useSSE bool
37 useAvg bool
38 useHmul bool
39 nacl bool
40 use387 bool
41 SoftFloat bool
42 Race bool
43 NeedsFpScratch bool
44 BigEndian bool
45 }
46
47 type (
48 blockRewriter func(*Block) bool
49 valueRewriter func(*Value) bool
50 )
51
52 type Types struct {
53 Bool *types.Type
54 Int8 *types.Type
55 Int16 *types.Type
56 Int32 *types.Type
57 Int64 *types.Type
58 UInt8 *types.Type
59 UInt16 *types.Type
60 UInt32 *types.Type
61 UInt64 *types.Type
62 Int *types.Type
63 Float32 *types.Type
64 Float64 *types.Type
65 UInt *types.Type
66 Uintptr *types.Type
67 String *types.Type
68 BytePtr *types.Type
69 Int32Ptr *types.Type
70 UInt32Ptr *types.Type
71 IntPtr *types.Type
72 UintptrPtr *types.Type
73 Float32Ptr *types.Type
74 Float64Ptr *types.Type
75 BytePtrPtr *types.Type
76 }
77
78
79 func NewTypes() *Types {
80 t := new(Types)
81 t.SetTypPtrs()
82 return t
83 }
84
85
86 func (t *Types) SetTypPtrs() {
87 t.Bool = types.Types[types.TBOOL]
88 t.Int8 = types.Types[types.TINT8]
89 t.Int16 = types.Types[types.TINT16]
90 t.Int32 = types.Types[types.TINT32]
91 t.Int64 = types.Types[types.TINT64]
92 t.UInt8 = types.Types[types.TUINT8]
93 t.UInt16 = types.Types[types.TUINT16]
94 t.UInt32 = types.Types[types.TUINT32]
95 t.UInt64 = types.Types[types.TUINT64]
96 t.Int = types.Types[types.TINT]
97 t.Float32 = types.Types[types.TFLOAT32]
98 t.Float64 = types.Types[types.TFLOAT64]
99 t.UInt = types.Types[types.TUINT]
100 t.Uintptr = types.Types[types.TUINTPTR]
101 t.String = types.Types[types.TSTRING]
102 t.BytePtr = types.NewPtr(types.Types[types.TUINT8])
103 t.Int32Ptr = types.NewPtr(types.Types[types.TINT32])
104 t.UInt32Ptr = types.NewPtr(types.Types[types.TUINT32])
105 t.IntPtr = types.NewPtr(types.Types[types.TINT])
106 t.UintptrPtr = types.NewPtr(types.Types[types.TUINTPTR])
107 t.Float32Ptr = types.NewPtr(types.Types[types.TFLOAT32])
108 t.Float64Ptr = types.NewPtr(types.Types[types.TFLOAT64])
109 t.BytePtrPtr = types.NewPtr(types.NewPtr(types.Types[types.TUINT8]))
110 }
111
112 type Logger interface {
113
114 Logf(string, ...interface{})
115
116
117
118 Log() bool
119
120
121 Fatalf(pos src.XPos, msg string, args ...interface{})
122
123
124 Warnl(pos src.XPos, fmt_ string, args ...interface{})
125
126
127 Debug_checknil() bool
128 }
129
130 type Frontend interface {
131 CanSSA(t *types.Type) bool
132
133 Logger
134
135
136 StringData(string) interface{}
137
138
139
140 Auto(src.XPos, *types.Type) GCNode
141
142
143
144 SplitString(LocalSlot) (LocalSlot, LocalSlot)
145 SplitInterface(LocalSlot) (LocalSlot, LocalSlot)
146 SplitSlice(LocalSlot) (LocalSlot, LocalSlot, LocalSlot)
147 SplitComplex(LocalSlot) (LocalSlot, LocalSlot)
148 SplitStruct(LocalSlot, int) LocalSlot
149 SplitArray(LocalSlot) LocalSlot
150 SplitInt64(LocalSlot) (LocalSlot, LocalSlot)
151
152
153
154
155
156 DerefItab(sym *obj.LSym, offset int64) *obj.LSym
157
158
159 Line(src.XPos) string
160
161
162 AllocFrame(f *Func)
163
164
165
166 Syslook(string) *obj.LSym
167
168
169 UseWriteBarrier() bool
170
171
172
173 SetWBPos(pos src.XPos)
174 }
175
176
177
178 type GCNode interface {
179 Typ() *types.Type
180 String() string
181 IsSynthetic() bool
182 IsAutoTmp() bool
183 StorageClass() StorageClass
184 }
185
186 type StorageClass uint8
187
188 const (
189 ClassAuto StorageClass = iota
190 ClassParam
191 ClassParamOut
192 )
193
194
195 func NewConfig(arch string, types Types, ctxt *obj.Link, optimize bool) *Config {
196 c := &Config{arch: arch, Types: types}
197 c.useAvg = true
198 c.useHmul = true
199 switch arch {
200 case "amd64":
201 c.PtrSize = 8
202 c.RegSize = 8
203 c.lowerBlock = rewriteBlockAMD64
204 c.lowerValue = rewriteValueAMD64
205 c.splitLoad = rewriteValueAMD64splitload
206 c.registers = registersAMD64[:]
207 c.gpRegMask = gpRegMaskAMD64
208 c.fpRegMask = fpRegMaskAMD64
209 c.FPReg = framepointerRegAMD64
210 c.LinkReg = linkRegAMD64
211 c.hasGReg = false
212 case "amd64p32":
213 c.PtrSize = 4
214 c.RegSize = 8
215 c.lowerBlock = rewriteBlockAMD64
216 c.lowerValue = rewriteValueAMD64
217 c.splitLoad = rewriteValueAMD64splitload
218 c.registers = registersAMD64[:]
219 c.gpRegMask = gpRegMaskAMD64
220 c.fpRegMask = fpRegMaskAMD64
221 c.FPReg = framepointerRegAMD64
222 c.LinkReg = linkRegAMD64
223 c.hasGReg = false
224 c.noDuffDevice = true
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"
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 "wasm":
320 c.PtrSize = 8
321 c.RegSize = 8
322 c.lowerBlock = rewriteBlockWasm
323 c.lowerValue = rewriteValueWasm
324 c.registers = registersWasm[:]
325 c.gpRegMask = gpRegMaskWasm
326 c.fpRegMask = fpRegMaskWasm
327 c.FPReg = framepointerRegWasm
328 c.LinkReg = linkRegWasm
329 c.hasGReg = true
330 c.noDuffDevice = true
331 c.useAvg = false
332 c.useHmul = false
333 default:
334 ctxt.Diag("arch %s not implemented", arch)
335 }
336 c.ctxt = ctxt
337 c.optimize = optimize
338 c.nacl = objabi.GOOS == "nacl"
339 c.useSSE = true
340
341
342
343 if objabi.GOOS == "plan9" && arch == "amd64" {
344 c.noDuffDevice = true
345 c.useSSE = false
346 }
347
348 if c.nacl {
349 c.noDuffDevice = true
350
351
352
353 opcodeTable[Op386LoweredWB].reg.clobbers |= 1 << 5
354
355
356 opcodeTable[OpAMD64LoweredWB].reg.clobbers |= 1 << 6
357 }
358
359 if ctxt.Flag_shared {
360
361
362
363 opcodeTable[Op386LoweredWB].reg.clobbers |= 1 << 3
364 }
365
366
367
368 gcRegMapSize := int16(0)
369 for _, r := range c.registers {
370 if r.gcNum+1 > gcRegMapSize {
371 gcRegMapSize = r.gcNum + 1
372 }
373 }
374 c.GCRegMap = make([]*Register, gcRegMapSize)
375 for i, r := range c.registers {
376 if r.gcNum != -1 {
377 c.GCRegMap[r.gcNum] = &c.registers[i]
378 }
379 }
380
381 return c
382 }
383
384 func (c *Config) Set387(b bool) {
385 c.NeedsFpScratch = b
386 c.use387 = b
387 }
388
389 func (c *Config) Ctxt() *obj.Link { return c.ctxt }
390
View as plain text