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