podman
716 строк · 20.7 Кб
1// Copyright 2015 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package arch defines architecture-specific information and support functions.
6package arch
7
8import (
9"github.com/twitchyliquid64/golang-asm/obj"
10"github.com/twitchyliquid64/golang-asm/obj/arm"
11"github.com/twitchyliquid64/golang-asm/obj/arm64"
12"github.com/twitchyliquid64/golang-asm/obj/mips"
13"github.com/twitchyliquid64/golang-asm/obj/ppc64"
14"github.com/twitchyliquid64/golang-asm/obj/riscv"
15"github.com/twitchyliquid64/golang-asm/obj/s390x"
16"github.com/twitchyliquid64/golang-asm/obj/wasm"
17"github.com/twitchyliquid64/golang-asm/obj/x86"
18"fmt"
19"strings"
20)
21
22// Pseudo-registers whose names are the constant name without the leading R.
23const (
24RFP = -(iota + 1)
25RSB
26RSP
27RPC
28)
29
30// Arch wraps the link architecture object with more architecture-specific information.
31type Arch struct {
32*obj.LinkArch
33// Map of instruction names to enumeration.
34Instructions map[string]obj.As
35// Map of register names to enumeration.
36Register map[string]int16
37// Table of register prefix names. These are things like R for R(0) and SPR for SPR(268).
38RegisterPrefix map[string]bool
39// RegisterNumber converts R(10) into arm.REG_R10.
40RegisterNumber func(string, int16) (int16, bool)
41// Instruction is a jump.
42IsJump func(word string) bool
43}
44
45// nilRegisterNumber is the register number function for architectures
46// that do not accept the R(N) notation. It always returns failure.
47func nilRegisterNumber(name string, n int16) (int16, bool) {
48return 0, false
49}
50
51// Set configures the architecture specified by GOARCH and returns its representation.
52// It returns nil if GOARCH is not recognized.
53func Set(GOARCH string) *Arch {
54switch GOARCH {
55case "386":
56return archX86(&x86.Link386)
57case "amd64":
58return archX86(&x86.Linkamd64)
59case "arm":
60return archArm()
61case "arm64":
62return archArm64()
63case "mips":
64return archMips(&mips.Linkmips)
65case "mipsle":
66return archMips(&mips.Linkmipsle)
67case "mips64":
68return archMips64(&mips.Linkmips64)
69case "mips64le":
70return archMips64(&mips.Linkmips64le)
71case "ppc64":
72return archPPC64(&ppc64.Linkppc64)
73case "ppc64le":
74return archPPC64(&ppc64.Linkppc64le)
75case "riscv64":
76return archRISCV64()
77case "s390x":
78return archS390x()
79case "wasm":
80return archWasm()
81}
82return nil
83}
84
85func jumpX86(word string) bool {
86return word[0] == 'J' || word == "CALL" || strings.HasPrefix(word, "LOOP") || word == "XBEGIN"
87}
88
89func jumpRISCV(word string) bool {
90switch word {
91case "BEQ", "BEQZ", "BGE", "BGEU", "BGEZ", "BGT", "BGTU", "BGTZ", "BLE", "BLEU", "BLEZ",
92"BLT", "BLTU", "BLTZ", "BNE", "BNEZ", "CALL", "JAL", "JALR", "JMP":
93return true
94}
95return false
96}
97
98func jumpWasm(word string) bool {
99return word == "JMP" || word == "CALL" || word == "Call" || word == "Br" || word == "BrIf"
100}
101
102func archX86(linkArch *obj.LinkArch) *Arch {
103register := make(map[string]int16)
104// Create maps for easy lookup of instruction names etc.
105for i, s := range x86.Register {
106register[s] = int16(i + x86.REG_AL)
107}
108// Pseudo-registers.
109register["SB"] = RSB
110register["FP"] = RFP
111register["PC"] = RPC
112// Register prefix not used on this architecture.
113
114instructions := make(map[string]obj.As)
115for i, s := range obj.Anames {
116instructions[s] = obj.As(i)
117}
118for i, s := range x86.Anames {
119if obj.As(i) >= obj.A_ARCHSPECIFIC {
120instructions[s] = obj.As(i) + obj.ABaseAMD64
121}
122}
123// Annoying aliases.
124instructions["JA"] = x86.AJHI /* alternate */
125instructions["JAE"] = x86.AJCC /* alternate */
126instructions["JB"] = x86.AJCS /* alternate */
127instructions["JBE"] = x86.AJLS /* alternate */
128instructions["JC"] = x86.AJCS /* alternate */
129instructions["JCC"] = x86.AJCC /* carry clear (CF = 0) */
130instructions["JCS"] = x86.AJCS /* carry set (CF = 1) */
131instructions["JE"] = x86.AJEQ /* alternate */
132instructions["JEQ"] = x86.AJEQ /* equal (ZF = 1) */
133instructions["JG"] = x86.AJGT /* alternate */
134instructions["JGE"] = x86.AJGE /* greater than or equal (signed) (SF = OF) */
135instructions["JGT"] = x86.AJGT /* greater than (signed) (ZF = 0 && SF = OF) */
136instructions["JHI"] = x86.AJHI /* higher (unsigned) (CF = 0 && ZF = 0) */
137instructions["JHS"] = x86.AJCC /* alternate */
138instructions["JL"] = x86.AJLT /* alternate */
139instructions["JLE"] = x86.AJLE /* less than or equal (signed) (ZF = 1 || SF != OF) */
140instructions["JLO"] = x86.AJCS /* alternate */
141instructions["JLS"] = x86.AJLS /* lower or same (unsigned) (CF = 1 || ZF = 1) */
142instructions["JLT"] = x86.AJLT /* less than (signed) (SF != OF) */
143instructions["JMI"] = x86.AJMI /* negative (minus) (SF = 1) */
144instructions["JNA"] = x86.AJLS /* alternate */
145instructions["JNAE"] = x86.AJCS /* alternate */
146instructions["JNB"] = x86.AJCC /* alternate */
147instructions["JNBE"] = x86.AJHI /* alternate */
148instructions["JNC"] = x86.AJCC /* alternate */
149instructions["JNE"] = x86.AJNE /* not equal (ZF = 0) */
150instructions["JNG"] = x86.AJLE /* alternate */
151instructions["JNGE"] = x86.AJLT /* alternate */
152instructions["JNL"] = x86.AJGE /* alternate */
153instructions["JNLE"] = x86.AJGT /* alternate */
154instructions["JNO"] = x86.AJOC /* alternate */
155instructions["JNP"] = x86.AJPC /* alternate */
156instructions["JNS"] = x86.AJPL /* alternate */
157instructions["JNZ"] = x86.AJNE /* alternate */
158instructions["JO"] = x86.AJOS /* alternate */
159instructions["JOC"] = x86.AJOC /* overflow clear (OF = 0) */
160instructions["JOS"] = x86.AJOS /* overflow set (OF = 1) */
161instructions["JP"] = x86.AJPS /* alternate */
162instructions["JPC"] = x86.AJPC /* parity clear (PF = 0) */
163instructions["JPE"] = x86.AJPS /* alternate */
164instructions["JPL"] = x86.AJPL /* non-negative (plus) (SF = 0) */
165instructions["JPO"] = x86.AJPC /* alternate */
166instructions["JPS"] = x86.AJPS /* parity set (PF = 1) */
167instructions["JS"] = x86.AJMI /* alternate */
168instructions["JZ"] = x86.AJEQ /* alternate */
169instructions["MASKMOVDQU"] = x86.AMASKMOVOU
170instructions["MOVD"] = x86.AMOVQ
171instructions["MOVDQ2Q"] = x86.AMOVQ
172instructions["MOVNTDQ"] = x86.AMOVNTO
173instructions["MOVOA"] = x86.AMOVO
174instructions["PSLLDQ"] = x86.APSLLO
175instructions["PSRLDQ"] = x86.APSRLO
176instructions["PADDD"] = x86.APADDL
177
178return &Arch{
179LinkArch: linkArch,
180Instructions: instructions,
181Register: register,
182RegisterPrefix: nil,
183RegisterNumber: nilRegisterNumber,
184IsJump: jumpX86,
185}
186}
187
188func archArm() *Arch {
189register := make(map[string]int16)
190// Create maps for easy lookup of instruction names etc.
191// Note that there is no list of names as there is for x86.
192for i := arm.REG_R0; i < arm.REG_SPSR; i++ {
193register[obj.Rconv(i)] = int16(i)
194}
195// Avoid unintentionally clobbering g using R10.
196delete(register, "R10")
197register["g"] = arm.REG_R10
198for i := 0; i < 16; i++ {
199register[fmt.Sprintf("C%d", i)] = int16(i)
200}
201
202// Pseudo-registers.
203register["SB"] = RSB
204register["FP"] = RFP
205register["PC"] = RPC
206register["SP"] = RSP
207registerPrefix := map[string]bool{
208"F": true,
209"R": true,
210}
211
212// special operands for DMB/DSB instructions
213register["MB_SY"] = arm.REG_MB_SY
214register["MB_ST"] = arm.REG_MB_ST
215register["MB_ISH"] = arm.REG_MB_ISH
216register["MB_ISHST"] = arm.REG_MB_ISHST
217register["MB_NSH"] = arm.REG_MB_NSH
218register["MB_NSHST"] = arm.REG_MB_NSHST
219register["MB_OSH"] = arm.REG_MB_OSH
220register["MB_OSHST"] = arm.REG_MB_OSHST
221
222instructions := make(map[string]obj.As)
223for i, s := range obj.Anames {
224instructions[s] = obj.As(i)
225}
226for i, s := range arm.Anames {
227if obj.As(i) >= obj.A_ARCHSPECIFIC {
228instructions[s] = obj.As(i) + obj.ABaseARM
229}
230}
231// Annoying aliases.
232instructions["B"] = obj.AJMP
233instructions["BL"] = obj.ACALL
234// MCR differs from MRC by the way fields of the word are encoded.
235// (Details in arm.go). Here we add the instruction so parse will find
236// it, but give it an opcode number known only to us.
237instructions["MCR"] = aMCR
238
239return &Arch{
240LinkArch: &arm.Linkarm,
241Instructions: instructions,
242Register: register,
243RegisterPrefix: registerPrefix,
244RegisterNumber: armRegisterNumber,
245IsJump: jumpArm,
246}
247}
248
249func archArm64() *Arch {
250register := make(map[string]int16)
251// Create maps for easy lookup of instruction names etc.
252// Note that there is no list of names as there is for 386 and amd64.
253register[obj.Rconv(arm64.REGSP)] = int16(arm64.REGSP)
254for i := arm64.REG_R0; i <= arm64.REG_R31; i++ {
255register[obj.Rconv(i)] = int16(i)
256}
257// Rename R18 to R18_PLATFORM to avoid accidental use.
258register["R18_PLATFORM"] = register["R18"]
259delete(register, "R18")
260for i := arm64.REG_F0; i <= arm64.REG_F31; i++ {
261register[obj.Rconv(i)] = int16(i)
262}
263for i := arm64.REG_V0; i <= arm64.REG_V31; i++ {
264register[obj.Rconv(i)] = int16(i)
265}
266
267// System registers.
268for i := 0; i < len(arm64.SystemReg); i++ {
269register[arm64.SystemReg[i].Name] = arm64.SystemReg[i].Reg
270}
271
272register["LR"] = arm64.REGLINK
273register["DAIFSet"] = arm64.REG_DAIFSet
274register["DAIFClr"] = arm64.REG_DAIFClr
275register["PLDL1KEEP"] = arm64.REG_PLDL1KEEP
276register["PLDL1STRM"] = arm64.REG_PLDL1STRM
277register["PLDL2KEEP"] = arm64.REG_PLDL2KEEP
278register["PLDL2STRM"] = arm64.REG_PLDL2STRM
279register["PLDL3KEEP"] = arm64.REG_PLDL3KEEP
280register["PLDL3STRM"] = arm64.REG_PLDL3STRM
281register["PLIL1KEEP"] = arm64.REG_PLIL1KEEP
282register["PLIL1STRM"] = arm64.REG_PLIL1STRM
283register["PLIL2KEEP"] = arm64.REG_PLIL2KEEP
284register["PLIL2STRM"] = arm64.REG_PLIL2STRM
285register["PLIL3KEEP"] = arm64.REG_PLIL3KEEP
286register["PLIL3STRM"] = arm64.REG_PLIL3STRM
287register["PSTL1KEEP"] = arm64.REG_PSTL1KEEP
288register["PSTL1STRM"] = arm64.REG_PSTL1STRM
289register["PSTL2KEEP"] = arm64.REG_PSTL2KEEP
290register["PSTL2STRM"] = arm64.REG_PSTL2STRM
291register["PSTL3KEEP"] = arm64.REG_PSTL3KEEP
292register["PSTL3STRM"] = arm64.REG_PSTL3STRM
293
294// Conditional operators, like EQ, NE, etc.
295register["EQ"] = arm64.COND_EQ
296register["NE"] = arm64.COND_NE
297register["HS"] = arm64.COND_HS
298register["CS"] = arm64.COND_HS
299register["LO"] = arm64.COND_LO
300register["CC"] = arm64.COND_LO
301register["MI"] = arm64.COND_MI
302register["PL"] = arm64.COND_PL
303register["VS"] = arm64.COND_VS
304register["VC"] = arm64.COND_VC
305register["HI"] = arm64.COND_HI
306register["LS"] = arm64.COND_LS
307register["GE"] = arm64.COND_GE
308register["LT"] = arm64.COND_LT
309register["GT"] = arm64.COND_GT
310register["LE"] = arm64.COND_LE
311register["AL"] = arm64.COND_AL
312register["NV"] = arm64.COND_NV
313// Pseudo-registers.
314register["SB"] = RSB
315register["FP"] = RFP
316register["PC"] = RPC
317register["SP"] = RSP
318// Avoid unintentionally clobbering g using R28.
319delete(register, "R28")
320register["g"] = arm64.REG_R28
321registerPrefix := map[string]bool{
322"F": true,
323"R": true,
324"V": true,
325}
326
327instructions := make(map[string]obj.As)
328for i, s := range obj.Anames {
329instructions[s] = obj.As(i)
330}
331for i, s := range arm64.Anames {
332if obj.As(i) >= obj.A_ARCHSPECIFIC {
333instructions[s] = obj.As(i) + obj.ABaseARM64
334}
335}
336// Annoying aliases.
337instructions["B"] = arm64.AB
338instructions["BL"] = arm64.ABL
339
340return &Arch{
341LinkArch: &arm64.Linkarm64,
342Instructions: instructions,
343Register: register,
344RegisterPrefix: registerPrefix,
345RegisterNumber: arm64RegisterNumber,
346IsJump: jumpArm64,
347}
348
349}
350
351func archPPC64(linkArch *obj.LinkArch) *Arch {
352register := make(map[string]int16)
353// Create maps for easy lookup of instruction names etc.
354// Note that there is no list of names as there is for x86.
355for i := ppc64.REG_R0; i <= ppc64.REG_R31; i++ {
356register[obj.Rconv(i)] = int16(i)
357}
358for i := ppc64.REG_F0; i <= ppc64.REG_F31; i++ {
359register[obj.Rconv(i)] = int16(i)
360}
361for i := ppc64.REG_V0; i <= ppc64.REG_V31; i++ {
362register[obj.Rconv(i)] = int16(i)
363}
364for i := ppc64.REG_VS0; i <= ppc64.REG_VS63; i++ {
365register[obj.Rconv(i)] = int16(i)
366}
367for i := ppc64.REG_CR0; i <= ppc64.REG_CR7; i++ {
368register[obj.Rconv(i)] = int16(i)
369}
370for i := ppc64.REG_MSR; i <= ppc64.REG_CR; i++ {
371register[obj.Rconv(i)] = int16(i)
372}
373register["CR"] = ppc64.REG_CR
374register["XER"] = ppc64.REG_XER
375register["LR"] = ppc64.REG_LR
376register["CTR"] = ppc64.REG_CTR
377register["FPSCR"] = ppc64.REG_FPSCR
378register["MSR"] = ppc64.REG_MSR
379// Pseudo-registers.
380register["SB"] = RSB
381register["FP"] = RFP
382register["PC"] = RPC
383// Avoid unintentionally clobbering g using R30.
384delete(register, "R30")
385register["g"] = ppc64.REG_R30
386registerPrefix := map[string]bool{
387"CR": true,
388"F": true,
389"R": true,
390"SPR": true,
391}
392
393instructions := make(map[string]obj.As)
394for i, s := range obj.Anames {
395instructions[s] = obj.As(i)
396}
397for i, s := range ppc64.Anames {
398if obj.As(i) >= obj.A_ARCHSPECIFIC {
399instructions[s] = obj.As(i) + obj.ABasePPC64
400}
401}
402// Annoying aliases.
403instructions["BR"] = ppc64.ABR
404instructions["BL"] = ppc64.ABL
405
406return &Arch{
407LinkArch: linkArch,
408Instructions: instructions,
409Register: register,
410RegisterPrefix: registerPrefix,
411RegisterNumber: ppc64RegisterNumber,
412IsJump: jumpPPC64,
413}
414}
415
416func archMips(linkArch *obj.LinkArch) *Arch {
417register := make(map[string]int16)
418// Create maps for easy lookup of instruction names etc.
419// Note that there is no list of names as there is for x86.
420for i := mips.REG_R0; i <= mips.REG_R31; i++ {
421register[obj.Rconv(i)] = int16(i)
422}
423
424for i := mips.REG_F0; i <= mips.REG_F31; i++ {
425register[obj.Rconv(i)] = int16(i)
426}
427for i := mips.REG_M0; i <= mips.REG_M31; i++ {
428register[obj.Rconv(i)] = int16(i)
429}
430for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ {
431register[obj.Rconv(i)] = int16(i)
432}
433register["HI"] = mips.REG_HI
434register["LO"] = mips.REG_LO
435// Pseudo-registers.
436register["SB"] = RSB
437register["FP"] = RFP
438register["PC"] = RPC
439// Avoid unintentionally clobbering g using R30.
440delete(register, "R30")
441register["g"] = mips.REG_R30
442
443registerPrefix := map[string]bool{
444"F": true,
445"FCR": true,
446"M": true,
447"R": true,
448}
449
450instructions := make(map[string]obj.As)
451for i, s := range obj.Anames {
452instructions[s] = obj.As(i)
453}
454for i, s := range mips.Anames {
455if obj.As(i) >= obj.A_ARCHSPECIFIC {
456instructions[s] = obj.As(i) + obj.ABaseMIPS
457}
458}
459// Annoying alias.
460instructions["JAL"] = mips.AJAL
461
462return &Arch{
463LinkArch: linkArch,
464Instructions: instructions,
465Register: register,
466RegisterPrefix: registerPrefix,
467RegisterNumber: mipsRegisterNumber,
468IsJump: jumpMIPS,
469}
470}
471
472func archMips64(linkArch *obj.LinkArch) *Arch {
473register := make(map[string]int16)
474// Create maps for easy lookup of instruction names etc.
475// Note that there is no list of names as there is for x86.
476for i := mips.REG_R0; i <= mips.REG_R31; i++ {
477register[obj.Rconv(i)] = int16(i)
478}
479for i := mips.REG_F0; i <= mips.REG_F31; i++ {
480register[obj.Rconv(i)] = int16(i)
481}
482for i := mips.REG_M0; i <= mips.REG_M31; i++ {
483register[obj.Rconv(i)] = int16(i)
484}
485for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ {
486register[obj.Rconv(i)] = int16(i)
487}
488for i := mips.REG_W0; i <= mips.REG_W31; i++ {
489register[obj.Rconv(i)] = int16(i)
490}
491register["HI"] = mips.REG_HI
492register["LO"] = mips.REG_LO
493// Pseudo-registers.
494register["SB"] = RSB
495register["FP"] = RFP
496register["PC"] = RPC
497// Avoid unintentionally clobbering g using R30.
498delete(register, "R30")
499register["g"] = mips.REG_R30
500// Avoid unintentionally clobbering RSB using R28.
501delete(register, "R28")
502register["RSB"] = mips.REG_R28
503registerPrefix := map[string]bool{
504"F": true,
505"FCR": true,
506"M": true,
507"R": true,
508"W": true,
509}
510
511instructions := make(map[string]obj.As)
512for i, s := range obj.Anames {
513instructions[s] = obj.As(i)
514}
515for i, s := range mips.Anames {
516if obj.As(i) >= obj.A_ARCHSPECIFIC {
517instructions[s] = obj.As(i) + obj.ABaseMIPS
518}
519}
520// Annoying alias.
521instructions["JAL"] = mips.AJAL
522
523return &Arch{
524LinkArch: linkArch,
525Instructions: instructions,
526Register: register,
527RegisterPrefix: registerPrefix,
528RegisterNumber: mipsRegisterNumber,
529IsJump: jumpMIPS,
530}
531}
532
533func archRISCV64() *Arch {
534register := make(map[string]int16)
535
536// Standard register names.
537for i := riscv.REG_X0; i <= riscv.REG_X31; i++ {
538name := fmt.Sprintf("X%d", i-riscv.REG_X0)
539register[name] = int16(i)
540}
541for i := riscv.REG_F0; i <= riscv.REG_F31; i++ {
542name := fmt.Sprintf("F%d", i-riscv.REG_F0)
543register[name] = int16(i)
544}
545
546// General registers with ABI names.
547register["ZERO"] = riscv.REG_ZERO
548register["RA"] = riscv.REG_RA
549register["SP"] = riscv.REG_SP
550register["GP"] = riscv.REG_GP
551register["TP"] = riscv.REG_TP
552register["T0"] = riscv.REG_T0
553register["T1"] = riscv.REG_T1
554register["T2"] = riscv.REG_T2
555register["S0"] = riscv.REG_S0
556register["S1"] = riscv.REG_S1
557register["A0"] = riscv.REG_A0
558register["A1"] = riscv.REG_A1
559register["A2"] = riscv.REG_A2
560register["A3"] = riscv.REG_A3
561register["A4"] = riscv.REG_A4
562register["A5"] = riscv.REG_A5
563register["A6"] = riscv.REG_A6
564register["A7"] = riscv.REG_A7
565register["S2"] = riscv.REG_S2
566register["S3"] = riscv.REG_S3
567register["S4"] = riscv.REG_S4
568register["S5"] = riscv.REG_S5
569register["S6"] = riscv.REG_S6
570register["S7"] = riscv.REG_S7
571register["S8"] = riscv.REG_S8
572register["S9"] = riscv.REG_S9
573register["S10"] = riscv.REG_S10
574register["S11"] = riscv.REG_S11
575register["T3"] = riscv.REG_T3
576register["T4"] = riscv.REG_T4
577register["T5"] = riscv.REG_T5
578register["T6"] = riscv.REG_T6
579
580// Go runtime register names.
581register["g"] = riscv.REG_G
582register["CTXT"] = riscv.REG_CTXT
583register["TMP"] = riscv.REG_TMP
584
585// ABI names for floating point register.
586register["FT0"] = riscv.REG_FT0
587register["FT1"] = riscv.REG_FT1
588register["FT2"] = riscv.REG_FT2
589register["FT3"] = riscv.REG_FT3
590register["FT4"] = riscv.REG_FT4
591register["FT5"] = riscv.REG_FT5
592register["FT6"] = riscv.REG_FT6
593register["FT7"] = riscv.REG_FT7
594register["FS0"] = riscv.REG_FS0
595register["FS1"] = riscv.REG_FS1
596register["FA0"] = riscv.REG_FA0
597register["FA1"] = riscv.REG_FA1
598register["FA2"] = riscv.REG_FA2
599register["FA3"] = riscv.REG_FA3
600register["FA4"] = riscv.REG_FA4
601register["FA5"] = riscv.REG_FA5
602register["FA6"] = riscv.REG_FA6
603register["FA7"] = riscv.REG_FA7
604register["FS2"] = riscv.REG_FS2
605register["FS3"] = riscv.REG_FS3
606register["FS4"] = riscv.REG_FS4
607register["FS5"] = riscv.REG_FS5
608register["FS6"] = riscv.REG_FS6
609register["FS7"] = riscv.REG_FS7
610register["FS8"] = riscv.REG_FS8
611register["FS9"] = riscv.REG_FS9
612register["FS10"] = riscv.REG_FS10
613register["FS11"] = riscv.REG_FS11
614register["FT8"] = riscv.REG_FT8
615register["FT9"] = riscv.REG_FT9
616register["FT10"] = riscv.REG_FT10
617register["FT11"] = riscv.REG_FT11
618
619// Pseudo-registers.
620register["SB"] = RSB
621register["FP"] = RFP
622register["PC"] = RPC
623
624instructions := make(map[string]obj.As)
625for i, s := range obj.Anames {
626instructions[s] = obj.As(i)
627}
628for i, s := range riscv.Anames {
629if obj.As(i) >= obj.A_ARCHSPECIFIC {
630instructions[s] = obj.As(i) + obj.ABaseRISCV
631}
632}
633
634return &Arch{
635LinkArch: &riscv.LinkRISCV64,
636Instructions: instructions,
637Register: register,
638RegisterPrefix: nil,
639RegisterNumber: nilRegisterNumber,
640IsJump: jumpRISCV,
641}
642}
643
644func archS390x() *Arch {
645register := make(map[string]int16)
646// Create maps for easy lookup of instruction names etc.
647// Note that there is no list of names as there is for x86.
648for i := s390x.REG_R0; i <= s390x.REG_R15; i++ {
649register[obj.Rconv(i)] = int16(i)
650}
651for i := s390x.REG_F0; i <= s390x.REG_F15; i++ {
652register[obj.Rconv(i)] = int16(i)
653}
654for i := s390x.REG_V0; i <= s390x.REG_V31; i++ {
655register[obj.Rconv(i)] = int16(i)
656}
657for i := s390x.REG_AR0; i <= s390x.REG_AR15; i++ {
658register[obj.Rconv(i)] = int16(i)
659}
660register["LR"] = s390x.REG_LR
661// Pseudo-registers.
662register["SB"] = RSB
663register["FP"] = RFP
664register["PC"] = RPC
665// Avoid unintentionally clobbering g using R13.
666delete(register, "R13")
667register["g"] = s390x.REG_R13
668registerPrefix := map[string]bool{
669"AR": true,
670"F": true,
671"R": true,
672}
673
674instructions := make(map[string]obj.As)
675for i, s := range obj.Anames {
676instructions[s] = obj.As(i)
677}
678for i, s := range s390x.Anames {
679if obj.As(i) >= obj.A_ARCHSPECIFIC {
680instructions[s] = obj.As(i) + obj.ABaseS390X
681}
682}
683// Annoying aliases.
684instructions["BR"] = s390x.ABR
685instructions["BL"] = s390x.ABL
686
687return &Arch{
688LinkArch: &s390x.Links390x,
689Instructions: instructions,
690Register: register,
691RegisterPrefix: registerPrefix,
692RegisterNumber: s390xRegisterNumber,
693IsJump: jumpS390x,
694}
695}
696
697func archWasm() *Arch {
698instructions := make(map[string]obj.As)
699for i, s := range obj.Anames {
700instructions[s] = obj.As(i)
701}
702for i, s := range wasm.Anames {
703if obj.As(i) >= obj.A_ARCHSPECIFIC {
704instructions[s] = obj.As(i) + obj.ABaseWasm
705}
706}
707
708return &Arch{
709LinkArch: &wasm.Linkwasm,
710Instructions: instructions,
711Register: wasm.Register,
712RegisterPrefix: nil,
713RegisterNumber: nilRegisterNumber,
714IsJump: jumpWasm,
715}
716}
717