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