Source file src/pkg/cmd/asm/internal/arch/arch.go
1
2
3
4
5
6 package arch
7
8 import (
9 "cmd/internal/obj"
10 "cmd/internal/obj/arm"
11 "cmd/internal/obj/arm64"
12 "cmd/internal/obj/mips"
13 "cmd/internal/obj/ppc64"
14 "cmd/internal/obj/s390x"
15 "cmd/internal/obj/wasm"
16 "cmd/internal/obj/x86"
17 "fmt"
18 "strings"
19 )
20
21
22 const (
23 RFP = -(iota + 1)
24 RSB
25 RSP
26 RPC
27 )
28
29
30 type Arch struct {
31 *obj.LinkArch
32
33 Instructions map[string]obj.As
34
35 Register map[string]int16
36
37 RegisterPrefix map[string]bool
38
39 RegisterNumber func(string, int16) (int16, bool)
40
41 IsJump func(word string) bool
42 }
43
44
45
46 func nilRegisterNumber(name string, n int16) (int16, bool) {
47 return 0, false
48 }
49
50
51
52 func Set(GOARCH string) *Arch {
53 switch GOARCH {
54 case "386":
55 return archX86(&x86.Link386)
56 case "amd64":
57 return archX86(&x86.Linkamd64)
58 case "amd64p32":
59 return archX86(&x86.Linkamd64p32)
60 case "arm":
61 return archArm()
62 case "arm64":
63 return archArm64()
64 case "mips":
65 a := archMips()
66 a.LinkArch = &mips.Linkmips
67 return a
68 case "mipsle":
69 a := archMips()
70 a.LinkArch = &mips.Linkmipsle
71 return a
72 case "mips64":
73 a := archMips64()
74 a.LinkArch = &mips.Linkmips64
75 return a
76 case "mips64le":
77 a := archMips64()
78 a.LinkArch = &mips.Linkmips64le
79 return a
80 case "ppc64":
81 a := archPPC64()
82 a.LinkArch = &ppc64.Linkppc64
83 return a
84 case "ppc64le":
85 a := archPPC64()
86 a.LinkArch = &ppc64.Linkppc64le
87 return a
88 case "s390x":
89 a := archS390x()
90 a.LinkArch = &s390x.Links390x
91 return a
92 case "wasm":
93 return archWasm()
94 }
95 return nil
96 }
97
98 func jumpX86(word string) bool {
99 return word[0] == 'J' || word == "CALL" || strings.HasPrefix(word, "LOOP") || word == "XBEGIN"
100 }
101
102 func jumpWasm(word string) bool {
103 return word == "JMP" || word == "CALL" || word == "Call" || word == "Br" || word == "BrIf"
104 }
105
106 func archX86(linkArch *obj.LinkArch) *Arch {
107 register := make(map[string]int16)
108
109 for i, s := range x86.Register {
110 register[s] = int16(i + x86.REG_AL)
111 }
112
113 register["SB"] = RSB
114 register["FP"] = RFP
115 register["PC"] = RPC
116
117
118 instructions := make(map[string]obj.As)
119 for i, s := range obj.Anames {
120 instructions[s] = obj.As(i)
121 }
122 for i, s := range x86.Anames {
123 if obj.As(i) >= obj.A_ARCHSPECIFIC {
124 instructions[s] = obj.As(i) + obj.ABaseAMD64
125 }
126 }
127
128 instructions["JA"] = x86.AJHI
129 instructions["JAE"] = x86.AJCC
130 instructions["JB"] = x86.AJCS
131 instructions["JBE"] = x86.AJLS
132 instructions["JC"] = x86.AJCS
133 instructions["JCC"] = x86.AJCC
134 instructions["JCS"] = x86.AJCS
135 instructions["JE"] = x86.AJEQ
136 instructions["JEQ"] = x86.AJEQ
137 instructions["JG"] = x86.AJGT
138 instructions["JGE"] = x86.AJGE
139 instructions["JGT"] = x86.AJGT
140 instructions["JHI"] = x86.AJHI
141 instructions["JHS"] = x86.AJCC
142 instructions["JL"] = x86.AJLT
143 instructions["JLE"] = x86.AJLE
144 instructions["JLO"] = x86.AJCS
145 instructions["JLS"] = x86.AJLS
146 instructions["JLT"] = x86.AJLT
147 instructions["JMI"] = x86.AJMI
148 instructions["JNA"] = x86.AJLS
149 instructions["JNAE"] = x86.AJCS
150 instructions["JNB"] = x86.AJCC
151 instructions["JNBE"] = x86.AJHI
152 instructions["JNC"] = x86.AJCC
153 instructions["JNE"] = x86.AJNE
154 instructions["JNG"] = x86.AJLE
155 instructions["JNGE"] = x86.AJLT
156 instructions["JNL"] = x86.AJGE
157 instructions["JNLE"] = x86.AJGT
158 instructions["JNO"] = x86.AJOC
159 instructions["JNP"] = x86.AJPC
160 instructions["JNS"] = x86.AJPL
161 instructions["JNZ"] = x86.AJNE
162 instructions["JO"] = x86.AJOS
163 instructions["JOC"] = x86.AJOC
164 instructions["JOS"] = x86.AJOS
165 instructions["JP"] = x86.AJPS
166 instructions["JPC"] = x86.AJPC
167 instructions["JPE"] = x86.AJPS
168 instructions["JPL"] = x86.AJPL
169 instructions["JPO"] = x86.AJPC
170 instructions["JPS"] = x86.AJPS
171 instructions["JS"] = x86.AJMI
172 instructions["JZ"] = x86.AJEQ
173 instructions["MASKMOVDQU"] = x86.AMASKMOVOU
174 instructions["MOVD"] = x86.AMOVQ
175 instructions["MOVDQ2Q"] = x86.AMOVQ
176 instructions["MOVNTDQ"] = x86.AMOVNTO
177 instructions["MOVOA"] = x86.AMOVO
178 instructions["PSLLDQ"] = x86.APSLLO
179 instructions["PSRLDQ"] = x86.APSRLO
180 instructions["PADDD"] = x86.APADDL
181
182 return &Arch{
183 LinkArch: linkArch,
184 Instructions: instructions,
185 Register: register,
186 RegisterPrefix: nil,
187 RegisterNumber: nilRegisterNumber,
188 IsJump: jumpX86,
189 }
190 }
191
192 func archArm() *Arch {
193 register := make(map[string]int16)
194
195
196 for i := arm.REG_R0; i < arm.REG_SPSR; i++ {
197 register[obj.Rconv(i)] = int16(i)
198 }
199
200 delete(register, "R10")
201 register["g"] = arm.REG_R10
202 for i := 0; i < 16; i++ {
203 register[fmt.Sprintf("C%d", i)] = int16(i)
204 }
205
206
207 register["SB"] = RSB
208 register["FP"] = RFP
209 register["PC"] = RPC
210 register["SP"] = RSP
211 registerPrefix := map[string]bool{
212 "F": true,
213 "R": true,
214 }
215
216
217 register["MB_SY"] = arm.REG_MB_SY
218 register["MB_ST"] = arm.REG_MB_ST
219 register["MB_ISH"] = arm.REG_MB_ISH
220 register["MB_ISHST"] = arm.REG_MB_ISHST
221 register["MB_NSH"] = arm.REG_MB_NSH
222 register["MB_NSHST"] = arm.REG_MB_NSHST
223 register["MB_OSH"] = arm.REG_MB_OSH
224 register["MB_OSHST"] = arm.REG_MB_OSHST
225
226 instructions := make(map[string]obj.As)
227 for i, s := range obj.Anames {
228 instructions[s] = obj.As(i)
229 }
230 for i, s := range arm.Anames {
231 if obj.As(i) >= obj.A_ARCHSPECIFIC {
232 instructions[s] = obj.As(i) + obj.ABaseARM
233 }
234 }
235
236 instructions["B"] = obj.AJMP
237 instructions["BL"] = obj.ACALL
238
239
240
241 instructions["MCR"] = aMCR
242
243 return &Arch{
244 LinkArch: &arm.Linkarm,
245 Instructions: instructions,
246 Register: register,
247 RegisterPrefix: registerPrefix,
248 RegisterNumber: armRegisterNumber,
249 IsJump: jumpArm,
250 }
251 }
252
253 func archArm64() *Arch {
254 register := make(map[string]int16)
255
256
257 register[obj.Rconv(arm64.REGSP)] = int16(arm64.REGSP)
258 for i := arm64.REG_R0; i <= arm64.REG_R31; i++ {
259 register[obj.Rconv(i)] = int16(i)
260 }
261
262 register["R18_PLATFORM"] = register["R18"]
263 delete(register, "R18")
264 for i := arm64.REG_F0; i <= arm64.REG_F31; i++ {
265 register[obj.Rconv(i)] = int16(i)
266 }
267 for i := arm64.REG_V0; i <= arm64.REG_V31; i++ {
268 register[obj.Rconv(i)] = int16(i)
269 }
270 register["LR"] = arm64.REGLINK
271 register["DAIF"] = arm64.REG_DAIF
272 register["NZCV"] = arm64.REG_NZCV
273 register["FPSR"] = arm64.REG_FPSR
274 register["FPCR"] = arm64.REG_FPCR
275 register["SPSR_EL1"] = arm64.REG_SPSR_EL1
276 register["ELR_EL1"] = arm64.REG_ELR_EL1
277 register["SPSR_EL2"] = arm64.REG_SPSR_EL2
278 register["ELR_EL2"] = arm64.REG_ELR_EL2
279 register["CurrentEL"] = arm64.REG_CurrentEL
280 register["SP_EL0"] = arm64.REG_SP_EL0
281 register["SPSel"] = arm64.REG_SPSel
282 register["DAIFSet"] = arm64.REG_DAIFSet
283 register["DAIFClr"] = arm64.REG_DAIFClr
284 register["DCZID_EL0"] = arm64.REG_DCZID_EL0
285 register["PLDL1KEEP"] = arm64.REG_PLDL1KEEP
286 register["PLDL1STRM"] = arm64.REG_PLDL1STRM
287 register["PLDL2KEEP"] = arm64.REG_PLDL2KEEP
288 register["PLDL2STRM"] = arm64.REG_PLDL2STRM
289 register["PLDL3KEEP"] = arm64.REG_PLDL3KEEP
290 register["PLDL3STRM"] = arm64.REG_PLDL3STRM
291 register["PLIL1KEEP"] = arm64.REG_PLIL1KEEP
292 register["PLIL1STRM"] = arm64.REG_PLIL1STRM
293 register["PLIL2KEEP"] = arm64.REG_PLIL2KEEP
294 register["PLIL2STRM"] = arm64.REG_PLIL2STRM
295 register["PLIL3KEEP"] = arm64.REG_PLIL3KEEP
296 register["PLIL3STRM"] = arm64.REG_PLIL3STRM
297 register["PSTL1KEEP"] = arm64.REG_PSTL1KEEP
298 register["PSTL1STRM"] = arm64.REG_PSTL1STRM
299 register["PSTL2KEEP"] = arm64.REG_PSTL2KEEP
300 register["PSTL2STRM"] = arm64.REG_PSTL2STRM
301 register["PSTL3KEEP"] = arm64.REG_PSTL3KEEP
302 register["PSTL3STRM"] = arm64.REG_PSTL3STRM
303
304
305 register["EQ"] = arm64.COND_EQ
306 register["NE"] = arm64.COND_NE
307 register["HS"] = arm64.COND_HS
308 register["CS"] = arm64.COND_HS
309 register["LO"] = arm64.COND_LO
310 register["CC"] = arm64.COND_LO
311 register["MI"] = arm64.COND_MI
312 register["PL"] = arm64.COND_PL
313 register["VS"] = arm64.COND_VS
314 register["VC"] = arm64.COND_VC
315 register["HI"] = arm64.COND_HI
316 register["LS"] = arm64.COND_LS
317 register["GE"] = arm64.COND_GE
318 register["LT"] = arm64.COND_LT
319 register["GT"] = arm64.COND_GT
320 register["LE"] = arm64.COND_LE
321 register["AL"] = arm64.COND_AL
322 register["NV"] = arm64.COND_NV
323
324 register["SB"] = RSB
325 register["FP"] = RFP
326 register["PC"] = RPC
327 register["SP"] = RSP
328
329 delete(register, "R28")
330 register["g"] = arm64.REG_R28
331 registerPrefix := map[string]bool{
332 "F": true,
333 "R": true,
334 "V": true,
335 }
336
337 instructions := make(map[string]obj.As)
338 for i, s := range obj.Anames {
339 instructions[s] = obj.As(i)
340 }
341 for i, s := range arm64.Anames {
342 if obj.As(i) >= obj.A_ARCHSPECIFIC {
343 instructions[s] = obj.As(i) + obj.ABaseARM64
344 }
345 }
346
347 instructions["B"] = arm64.AB
348 instructions["BL"] = arm64.ABL
349
350 return &Arch{
351 LinkArch: &arm64.Linkarm64,
352 Instructions: instructions,
353 Register: register,
354 RegisterPrefix: registerPrefix,
355 RegisterNumber: arm64RegisterNumber,
356 IsJump: jumpArm64,
357 }
358
359 }
360
361 func archPPC64() *Arch {
362 register := make(map[string]int16)
363
364
365 for i := ppc64.REG_R0; i <= ppc64.REG_R31; i++ {
366 register[obj.Rconv(i)] = int16(i)
367 }
368 for i := ppc64.REG_F0; i <= ppc64.REG_F31; i++ {
369 register[obj.Rconv(i)] = int16(i)
370 }
371 for i := ppc64.REG_V0; i <= ppc64.REG_V31; i++ {
372 register[obj.Rconv(i)] = int16(i)
373 }
374 for i := ppc64.REG_VS0; i <= ppc64.REG_VS63; i++ {
375 register[obj.Rconv(i)] = int16(i)
376 }
377 for i := ppc64.REG_CR0; i <= ppc64.REG_CR7; i++ {
378 register[obj.Rconv(i)] = int16(i)
379 }
380 for i := ppc64.REG_MSR; i <= ppc64.REG_CR; i++ {
381 register[obj.Rconv(i)] = int16(i)
382 }
383 register["CR"] = ppc64.REG_CR
384 register["XER"] = ppc64.REG_XER
385 register["LR"] = ppc64.REG_LR
386 register["CTR"] = ppc64.REG_CTR
387 register["FPSCR"] = ppc64.REG_FPSCR
388 register["MSR"] = ppc64.REG_MSR
389
390 register["SB"] = RSB
391 register["FP"] = RFP
392 register["PC"] = RPC
393
394 delete(register, "R30")
395 register["g"] = ppc64.REG_R30
396 registerPrefix := map[string]bool{
397 "CR": true,
398 "F": true,
399 "R": true,
400 "SPR": true,
401 }
402
403 instructions := make(map[string]obj.As)
404 for i, s := range obj.Anames {
405 instructions[s] = obj.As(i)
406 }
407 for i, s := range ppc64.Anames {
408 if obj.As(i) >= obj.A_ARCHSPECIFIC {
409 instructions[s] = obj.As(i) + obj.ABasePPC64
410 }
411 }
412
413 instructions["BR"] = ppc64.ABR
414 instructions["BL"] = ppc64.ABL
415
416 return &Arch{
417 LinkArch: &ppc64.Linkppc64,
418 Instructions: instructions,
419 Register: register,
420 RegisterPrefix: registerPrefix,
421 RegisterNumber: ppc64RegisterNumber,
422 IsJump: jumpPPC64,
423 }
424 }
425
426 func archMips() *Arch {
427 register := make(map[string]int16)
428
429
430 for i := mips.REG_R0; i <= mips.REG_R31; i++ {
431 register[obj.Rconv(i)] = int16(i)
432 }
433
434 for i := mips.REG_F0; i <= mips.REG_F31; i++ {
435 register[obj.Rconv(i)] = int16(i)
436 }
437 for i := mips.REG_M0; i <= mips.REG_M31; i++ {
438 register[obj.Rconv(i)] = int16(i)
439 }
440 for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ {
441 register[obj.Rconv(i)] = int16(i)
442 }
443 register["HI"] = mips.REG_HI
444 register["LO"] = mips.REG_LO
445
446 register["SB"] = RSB
447 register["FP"] = RFP
448 register["PC"] = RPC
449
450 delete(register, "R30")
451 register["g"] = mips.REG_R30
452
453 registerPrefix := map[string]bool{
454 "F": true,
455 "FCR": true,
456 "M": true,
457 "R": true,
458 }
459
460 instructions := make(map[string]obj.As)
461 for i, s := range obj.Anames {
462 instructions[s] = obj.As(i)
463 }
464 for i, s := range mips.Anames {
465 if obj.As(i) >= obj.A_ARCHSPECIFIC {
466 instructions[s] = obj.As(i) + obj.ABaseMIPS
467 }
468 }
469
470 instructions["JAL"] = mips.AJAL
471
472 return &Arch{
473 LinkArch: &mips.Linkmipsle,
474 Instructions: instructions,
475 Register: register,
476 RegisterPrefix: registerPrefix,
477 RegisterNumber: mipsRegisterNumber,
478 IsJump: jumpMIPS,
479 }
480 }
481
482 func archMips64() *Arch {
483 register := make(map[string]int16)
484
485
486 for i := mips.REG_R0; i <= mips.REG_R31; i++ {
487 register[obj.Rconv(i)] = int16(i)
488 }
489 for i := mips.REG_F0; i <= mips.REG_F31; i++ {
490 register[obj.Rconv(i)] = int16(i)
491 }
492 for i := mips.REG_M0; i <= mips.REG_M31; i++ {
493 register[obj.Rconv(i)] = int16(i)
494 }
495 for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ {
496 register[obj.Rconv(i)] = int16(i)
497 }
498 register["HI"] = mips.REG_HI
499 register["LO"] = mips.REG_LO
500
501 register["SB"] = RSB
502 register["FP"] = RFP
503 register["PC"] = RPC
504
505 delete(register, "R30")
506 register["g"] = mips.REG_R30
507
508 delete(register, "R28")
509 register["RSB"] = mips.REG_R28
510 registerPrefix := map[string]bool{
511 "F": true,
512 "FCR": true,
513 "M": true,
514 "R": true,
515 }
516
517 instructions := make(map[string]obj.As)
518 for i, s := range obj.Anames {
519 instructions[s] = obj.As(i)
520 }
521 for i, s := range mips.Anames {
522 if obj.As(i) >= obj.A_ARCHSPECIFIC {
523 instructions[s] = obj.As(i) + obj.ABaseMIPS
524 }
525 }
526
527 instructions["JAL"] = mips.AJAL
528
529 return &Arch{
530 LinkArch: &mips.Linkmips64,
531 Instructions: instructions,
532 Register: register,
533 RegisterPrefix: registerPrefix,
534 RegisterNumber: mipsRegisterNumber,
535 IsJump: jumpMIPS,
536 }
537 }
538
539 func archS390x() *Arch {
540 register := make(map[string]int16)
541
542
543 for i := s390x.REG_R0; i <= s390x.REG_R15; i++ {
544 register[obj.Rconv(i)] = int16(i)
545 }
546 for i := s390x.REG_F0; i <= s390x.REG_F15; i++ {
547 register[obj.Rconv(i)] = int16(i)
548 }
549 for i := s390x.REG_V0; i <= s390x.REG_V31; i++ {
550 register[obj.Rconv(i)] = int16(i)
551 }
552 for i := s390x.REG_AR0; i <= s390x.REG_AR15; i++ {
553 register[obj.Rconv(i)] = int16(i)
554 }
555 register["LR"] = s390x.REG_LR
556
557 register["SB"] = RSB
558 register["FP"] = RFP
559 register["PC"] = RPC
560
561 delete(register, "R13")
562 register["g"] = s390x.REG_R13
563 registerPrefix := map[string]bool{
564 "AR": true,
565 "F": true,
566 "R": true,
567 }
568
569 instructions := make(map[string]obj.As)
570 for i, s := range obj.Anames {
571 instructions[s] = obj.As(i)
572 }
573 for i, s := range s390x.Anames {
574 if obj.As(i) >= obj.A_ARCHSPECIFIC {
575 instructions[s] = obj.As(i) + obj.ABaseS390X
576 }
577 }
578
579 instructions["BR"] = s390x.ABR
580 instructions["BL"] = s390x.ABL
581
582 return &Arch{
583 LinkArch: &s390x.Links390x,
584 Instructions: instructions,
585 Register: register,
586 RegisterPrefix: registerPrefix,
587 RegisterNumber: s390xRegisterNumber,
588 IsJump: jumpS390x,
589 }
590 }
591
592 func archWasm() *Arch {
593 instructions := make(map[string]obj.As)
594 for i, s := range obj.Anames {
595 instructions[s] = obj.As(i)
596 }
597 for i, s := range wasm.Anames {
598 if obj.As(i) >= obj.A_ARCHSPECIFIC {
599 instructions[s] = obj.As(i) + obj.ABaseWasm
600 }
601 }
602
603 return &Arch{
604 LinkArch: &wasm.Linkwasm,
605 Instructions: instructions,
606 Register: wasm.Register,
607 RegisterPrefix: nil,
608 RegisterNumber: nilRegisterNumber,
609 IsJump: jumpWasm,
610 }
611 }
612
View as plain text