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