podman

Форк
0
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.
6
package arch
7

8
import (
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.
23
const (
24
	RFP = -(iota + 1)
25
	RSB
26
	RSP
27
	RPC
28
)
29

30
// Arch wraps the link architecture object with more architecture-specific information.
31
type Arch struct {
32
	*obj.LinkArch
33
	// Map of instruction names to enumeration.
34
	Instructions map[string]obj.As
35
	// Map of register names to enumeration.
36
	Register map[string]int16
37
	// Table of register prefix names. These are things like R for R(0) and SPR for SPR(268).
38
	RegisterPrefix map[string]bool
39
	// RegisterNumber converts R(10) into arm.REG_R10.
40
	RegisterNumber func(string, int16) (int16, bool)
41
	// Instruction is a jump.
42
	IsJump 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.
47
func nilRegisterNumber(name string, n int16) (int16, bool) {
48
	return 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.
53
func Set(GOARCH string) *Arch {
54
	switch GOARCH {
55
	case "386":
56
		return archX86(&x86.Link386)
57
	case "amd64":
58
		return archX86(&x86.Linkamd64)
59
	case "arm":
60
		return archArm()
61
	case "arm64":
62
		return archArm64()
63
	case "mips":
64
		return archMips(&mips.Linkmips)
65
	case "mipsle":
66
		return archMips(&mips.Linkmipsle)
67
	case "mips64":
68
		return archMips64(&mips.Linkmips64)
69
	case "mips64le":
70
		return archMips64(&mips.Linkmips64le)
71
	case "ppc64":
72
		return archPPC64(&ppc64.Linkppc64)
73
	case "ppc64le":
74
		return archPPC64(&ppc64.Linkppc64le)
75
	case "riscv64":
76
		return archRISCV64()
77
	case "s390x":
78
		return archS390x()
79
	case "wasm":
80
		return archWasm()
81
	}
82
	return nil
83
}
84

85
func jumpX86(word string) bool {
86
	return word[0] == 'J' || word == "CALL" || strings.HasPrefix(word, "LOOP") || word == "XBEGIN"
87
}
88

89
func jumpRISCV(word string) bool {
90
	switch word {
91
	case "BEQ", "BEQZ", "BGE", "BGEU", "BGEZ", "BGT", "BGTU", "BGTZ", "BLE", "BLEU", "BLEZ",
92
		"BLT", "BLTU", "BLTZ", "BNE", "BNEZ", "CALL", "JAL", "JALR", "JMP":
93
		return true
94
	}
95
	return false
96
}
97

98
func jumpWasm(word string) bool {
99
	return word == "JMP" || word == "CALL" || word == "Call" || word == "Br" || word == "BrIf"
100
}
101

102
func archX86(linkArch *obj.LinkArch) *Arch {
103
	register := make(map[string]int16)
104
	// Create maps for easy lookup of instruction names etc.
105
	for i, s := range x86.Register {
106
		register[s] = int16(i + x86.REG_AL)
107
	}
108
	// Pseudo-registers.
109
	register["SB"] = RSB
110
	register["FP"] = RFP
111
	register["PC"] = RPC
112
	// Register prefix not used on this architecture.
113

114
	instructions := make(map[string]obj.As)
115
	for i, s := range obj.Anames {
116
		instructions[s] = obj.As(i)
117
	}
118
	for i, s := range x86.Anames {
119
		if obj.As(i) >= obj.A_ARCHSPECIFIC {
120
			instructions[s] = obj.As(i) + obj.ABaseAMD64
121
		}
122
	}
123
	// Annoying aliases.
124
	instructions["JA"] = x86.AJHI   /* alternate */
125
	instructions["JAE"] = x86.AJCC  /* alternate */
126
	instructions["JB"] = x86.AJCS   /* alternate */
127
	instructions["JBE"] = x86.AJLS  /* alternate */
128
	instructions["JC"] = x86.AJCS   /* alternate */
129
	instructions["JCC"] = x86.AJCC  /* carry clear (CF = 0) */
130
	instructions["JCS"] = x86.AJCS  /* carry set (CF = 1) */
131
	instructions["JE"] = x86.AJEQ   /* alternate */
132
	instructions["JEQ"] = x86.AJEQ  /* equal (ZF = 1) */
133
	instructions["JG"] = x86.AJGT   /* alternate */
134
	instructions["JGE"] = x86.AJGE  /* greater than or equal (signed) (SF = OF) */
135
	instructions["JGT"] = x86.AJGT  /* greater than (signed) (ZF = 0 && SF = OF) */
136
	instructions["JHI"] = x86.AJHI  /* higher (unsigned) (CF = 0 && ZF = 0) */
137
	instructions["JHS"] = x86.AJCC  /* alternate */
138
	instructions["JL"] = x86.AJLT   /* alternate */
139
	instructions["JLE"] = x86.AJLE  /* less than or equal (signed) (ZF = 1 || SF != OF) */
140
	instructions["JLO"] = x86.AJCS  /* alternate */
141
	instructions["JLS"] = x86.AJLS  /* lower or same (unsigned) (CF = 1 || ZF = 1) */
142
	instructions["JLT"] = x86.AJLT  /* less than (signed) (SF != OF) */
143
	instructions["JMI"] = x86.AJMI  /* negative (minus) (SF = 1) */
144
	instructions["JNA"] = x86.AJLS  /* alternate */
145
	instructions["JNAE"] = x86.AJCS /* alternate */
146
	instructions["JNB"] = x86.AJCC  /* alternate */
147
	instructions["JNBE"] = x86.AJHI /* alternate */
148
	instructions["JNC"] = x86.AJCC  /* alternate */
149
	instructions["JNE"] = x86.AJNE  /* not equal (ZF = 0) */
150
	instructions["JNG"] = x86.AJLE  /* alternate */
151
	instructions["JNGE"] = x86.AJLT /* alternate */
152
	instructions["JNL"] = x86.AJGE  /* alternate */
153
	instructions["JNLE"] = x86.AJGT /* alternate */
154
	instructions["JNO"] = x86.AJOC  /* alternate */
155
	instructions["JNP"] = x86.AJPC  /* alternate */
156
	instructions["JNS"] = x86.AJPL  /* alternate */
157
	instructions["JNZ"] = x86.AJNE  /* alternate */
158
	instructions["JO"] = x86.AJOS   /* alternate */
159
	instructions["JOC"] = x86.AJOC  /* overflow clear (OF = 0) */
160
	instructions["JOS"] = x86.AJOS  /* overflow set (OF = 1) */
161
	instructions["JP"] = x86.AJPS   /* alternate */
162
	instructions["JPC"] = x86.AJPC  /* parity clear (PF = 0) */
163
	instructions["JPE"] = x86.AJPS  /* alternate */
164
	instructions["JPL"] = x86.AJPL  /* non-negative (plus) (SF = 0) */
165
	instructions["JPO"] = x86.AJPC  /* alternate */
166
	instructions["JPS"] = x86.AJPS  /* parity set (PF = 1) */
167
	instructions["JS"] = x86.AJMI   /* alternate */
168
	instructions["JZ"] = x86.AJEQ   /* alternate */
169
	instructions["MASKMOVDQU"] = x86.AMASKMOVOU
170
	instructions["MOVD"] = x86.AMOVQ
171
	instructions["MOVDQ2Q"] = x86.AMOVQ
172
	instructions["MOVNTDQ"] = x86.AMOVNTO
173
	instructions["MOVOA"] = x86.AMOVO
174
	instructions["PSLLDQ"] = x86.APSLLO
175
	instructions["PSRLDQ"] = x86.APSRLO
176
	instructions["PADDD"] = x86.APADDL
177

178
	return &Arch{
179
		LinkArch:       linkArch,
180
		Instructions:   instructions,
181
		Register:       register,
182
		RegisterPrefix: nil,
183
		RegisterNumber: nilRegisterNumber,
184
		IsJump:         jumpX86,
185
	}
186
}
187

188
func archArm() *Arch {
189
	register := 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.
192
	for i := arm.REG_R0; i < arm.REG_SPSR; i++ {
193
		register[obj.Rconv(i)] = int16(i)
194
	}
195
	// Avoid unintentionally clobbering g using R10.
196
	delete(register, "R10")
197
	register["g"] = arm.REG_R10
198
	for i := 0; i < 16; i++ {
199
		register[fmt.Sprintf("C%d", i)] = int16(i)
200
	}
201

202
	// Pseudo-registers.
203
	register["SB"] = RSB
204
	register["FP"] = RFP
205
	register["PC"] = RPC
206
	register["SP"] = RSP
207
	registerPrefix := map[string]bool{
208
		"F": true,
209
		"R": true,
210
	}
211

212
	// special operands for DMB/DSB instructions
213
	register["MB_SY"] = arm.REG_MB_SY
214
	register["MB_ST"] = arm.REG_MB_ST
215
	register["MB_ISH"] = arm.REG_MB_ISH
216
	register["MB_ISHST"] = arm.REG_MB_ISHST
217
	register["MB_NSH"] = arm.REG_MB_NSH
218
	register["MB_NSHST"] = arm.REG_MB_NSHST
219
	register["MB_OSH"] = arm.REG_MB_OSH
220
	register["MB_OSHST"] = arm.REG_MB_OSHST
221

222
	instructions := make(map[string]obj.As)
223
	for i, s := range obj.Anames {
224
		instructions[s] = obj.As(i)
225
	}
226
	for i, s := range arm.Anames {
227
		if obj.As(i) >= obj.A_ARCHSPECIFIC {
228
			instructions[s] = obj.As(i) + obj.ABaseARM
229
		}
230
	}
231
	// Annoying aliases.
232
	instructions["B"] = obj.AJMP
233
	instructions["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.
237
	instructions["MCR"] = aMCR
238

239
	return &Arch{
240
		LinkArch:       &arm.Linkarm,
241
		Instructions:   instructions,
242
		Register:       register,
243
		RegisterPrefix: registerPrefix,
244
		RegisterNumber: armRegisterNumber,
245
		IsJump:         jumpArm,
246
	}
247
}
248

249
func archArm64() *Arch {
250
	register := 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.
253
	register[obj.Rconv(arm64.REGSP)] = int16(arm64.REGSP)
254
	for i := arm64.REG_R0; i <= arm64.REG_R31; i++ {
255
		register[obj.Rconv(i)] = int16(i)
256
	}
257
	// Rename R18 to R18_PLATFORM to avoid accidental use.
258
	register["R18_PLATFORM"] = register["R18"]
259
	delete(register, "R18")
260
	for i := arm64.REG_F0; i <= arm64.REG_F31; i++ {
261
		register[obj.Rconv(i)] = int16(i)
262
	}
263
	for i := arm64.REG_V0; i <= arm64.REG_V31; i++ {
264
		register[obj.Rconv(i)] = int16(i)
265
	}
266

267
	// System registers.
268
	for i := 0; i < len(arm64.SystemReg); i++ {
269
		register[arm64.SystemReg[i].Name] = arm64.SystemReg[i].Reg
270
	}
271

272
	register["LR"] = arm64.REGLINK
273
	register["DAIFSet"] = arm64.REG_DAIFSet
274
	register["DAIFClr"] = arm64.REG_DAIFClr
275
	register["PLDL1KEEP"] = arm64.REG_PLDL1KEEP
276
	register["PLDL1STRM"] = arm64.REG_PLDL1STRM
277
	register["PLDL2KEEP"] = arm64.REG_PLDL2KEEP
278
	register["PLDL2STRM"] = arm64.REG_PLDL2STRM
279
	register["PLDL3KEEP"] = arm64.REG_PLDL3KEEP
280
	register["PLDL3STRM"] = arm64.REG_PLDL3STRM
281
	register["PLIL1KEEP"] = arm64.REG_PLIL1KEEP
282
	register["PLIL1STRM"] = arm64.REG_PLIL1STRM
283
	register["PLIL2KEEP"] = arm64.REG_PLIL2KEEP
284
	register["PLIL2STRM"] = arm64.REG_PLIL2STRM
285
	register["PLIL3KEEP"] = arm64.REG_PLIL3KEEP
286
	register["PLIL3STRM"] = arm64.REG_PLIL3STRM
287
	register["PSTL1KEEP"] = arm64.REG_PSTL1KEEP
288
	register["PSTL1STRM"] = arm64.REG_PSTL1STRM
289
	register["PSTL2KEEP"] = arm64.REG_PSTL2KEEP
290
	register["PSTL2STRM"] = arm64.REG_PSTL2STRM
291
	register["PSTL3KEEP"] = arm64.REG_PSTL3KEEP
292
	register["PSTL3STRM"] = arm64.REG_PSTL3STRM
293

294
	// Conditional operators, like EQ, NE, etc.
295
	register["EQ"] = arm64.COND_EQ
296
	register["NE"] = arm64.COND_NE
297
	register["HS"] = arm64.COND_HS
298
	register["CS"] = arm64.COND_HS
299
	register["LO"] = arm64.COND_LO
300
	register["CC"] = arm64.COND_LO
301
	register["MI"] = arm64.COND_MI
302
	register["PL"] = arm64.COND_PL
303
	register["VS"] = arm64.COND_VS
304
	register["VC"] = arm64.COND_VC
305
	register["HI"] = arm64.COND_HI
306
	register["LS"] = arm64.COND_LS
307
	register["GE"] = arm64.COND_GE
308
	register["LT"] = arm64.COND_LT
309
	register["GT"] = arm64.COND_GT
310
	register["LE"] = arm64.COND_LE
311
	register["AL"] = arm64.COND_AL
312
	register["NV"] = arm64.COND_NV
313
	// Pseudo-registers.
314
	register["SB"] = RSB
315
	register["FP"] = RFP
316
	register["PC"] = RPC
317
	register["SP"] = RSP
318
	// Avoid unintentionally clobbering g using R28.
319
	delete(register, "R28")
320
	register["g"] = arm64.REG_R28
321
	registerPrefix := map[string]bool{
322
		"F": true,
323
		"R": true,
324
		"V": true,
325
	}
326

327
	instructions := make(map[string]obj.As)
328
	for i, s := range obj.Anames {
329
		instructions[s] = obj.As(i)
330
	}
331
	for i, s := range arm64.Anames {
332
		if obj.As(i) >= obj.A_ARCHSPECIFIC {
333
			instructions[s] = obj.As(i) + obj.ABaseARM64
334
		}
335
	}
336
	// Annoying aliases.
337
	instructions["B"] = arm64.AB
338
	instructions["BL"] = arm64.ABL
339

340
	return &Arch{
341
		LinkArch:       &arm64.Linkarm64,
342
		Instructions:   instructions,
343
		Register:       register,
344
		RegisterPrefix: registerPrefix,
345
		RegisterNumber: arm64RegisterNumber,
346
		IsJump:         jumpArm64,
347
	}
348

349
}
350

351
func archPPC64(linkArch *obj.LinkArch) *Arch {
352
	register := 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.
355
	for i := ppc64.REG_R0; i <= ppc64.REG_R31; i++ {
356
		register[obj.Rconv(i)] = int16(i)
357
	}
358
	for i := ppc64.REG_F0; i <= ppc64.REG_F31; i++ {
359
		register[obj.Rconv(i)] = int16(i)
360
	}
361
	for i := ppc64.REG_V0; i <= ppc64.REG_V31; i++ {
362
		register[obj.Rconv(i)] = int16(i)
363
	}
364
	for i := ppc64.REG_VS0; i <= ppc64.REG_VS63; i++ {
365
		register[obj.Rconv(i)] = int16(i)
366
	}
367
	for i := ppc64.REG_CR0; i <= ppc64.REG_CR7; i++ {
368
		register[obj.Rconv(i)] = int16(i)
369
	}
370
	for i := ppc64.REG_MSR; i <= ppc64.REG_CR; i++ {
371
		register[obj.Rconv(i)] = int16(i)
372
	}
373
	register["CR"] = ppc64.REG_CR
374
	register["XER"] = ppc64.REG_XER
375
	register["LR"] = ppc64.REG_LR
376
	register["CTR"] = ppc64.REG_CTR
377
	register["FPSCR"] = ppc64.REG_FPSCR
378
	register["MSR"] = ppc64.REG_MSR
379
	// Pseudo-registers.
380
	register["SB"] = RSB
381
	register["FP"] = RFP
382
	register["PC"] = RPC
383
	// Avoid unintentionally clobbering g using R30.
384
	delete(register, "R30")
385
	register["g"] = ppc64.REG_R30
386
	registerPrefix := map[string]bool{
387
		"CR":  true,
388
		"F":   true,
389
		"R":   true,
390
		"SPR": true,
391
	}
392

393
	instructions := make(map[string]obj.As)
394
	for i, s := range obj.Anames {
395
		instructions[s] = obj.As(i)
396
	}
397
	for i, s := range ppc64.Anames {
398
		if obj.As(i) >= obj.A_ARCHSPECIFIC {
399
			instructions[s] = obj.As(i) + obj.ABasePPC64
400
		}
401
	}
402
	// Annoying aliases.
403
	instructions["BR"] = ppc64.ABR
404
	instructions["BL"] = ppc64.ABL
405

406
	return &Arch{
407
		LinkArch:       linkArch,
408
		Instructions:   instructions,
409
		Register:       register,
410
		RegisterPrefix: registerPrefix,
411
		RegisterNumber: ppc64RegisterNumber,
412
		IsJump:         jumpPPC64,
413
	}
414
}
415

416
func archMips(linkArch *obj.LinkArch) *Arch {
417
	register := 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.
420
	for i := mips.REG_R0; i <= mips.REG_R31; i++ {
421
		register[obj.Rconv(i)] = int16(i)
422
	}
423

424
	for i := mips.REG_F0; i <= mips.REG_F31; i++ {
425
		register[obj.Rconv(i)] = int16(i)
426
	}
427
	for i := mips.REG_M0; i <= mips.REG_M31; i++ {
428
		register[obj.Rconv(i)] = int16(i)
429
	}
430
	for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ {
431
		register[obj.Rconv(i)] = int16(i)
432
	}
433
	register["HI"] = mips.REG_HI
434
	register["LO"] = mips.REG_LO
435
	// Pseudo-registers.
436
	register["SB"] = RSB
437
	register["FP"] = RFP
438
	register["PC"] = RPC
439
	// Avoid unintentionally clobbering g using R30.
440
	delete(register, "R30")
441
	register["g"] = mips.REG_R30
442

443
	registerPrefix := map[string]bool{
444
		"F":   true,
445
		"FCR": true,
446
		"M":   true,
447
		"R":   true,
448
	}
449

450
	instructions := make(map[string]obj.As)
451
	for i, s := range obj.Anames {
452
		instructions[s] = obj.As(i)
453
	}
454
	for i, s := range mips.Anames {
455
		if obj.As(i) >= obj.A_ARCHSPECIFIC {
456
			instructions[s] = obj.As(i) + obj.ABaseMIPS
457
		}
458
	}
459
	// Annoying alias.
460
	instructions["JAL"] = mips.AJAL
461

462
	return &Arch{
463
		LinkArch:       linkArch,
464
		Instructions:   instructions,
465
		Register:       register,
466
		RegisterPrefix: registerPrefix,
467
		RegisterNumber: mipsRegisterNumber,
468
		IsJump:         jumpMIPS,
469
	}
470
}
471

472
func archMips64(linkArch *obj.LinkArch) *Arch {
473
	register := 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.
476
	for i := mips.REG_R0; i <= mips.REG_R31; i++ {
477
		register[obj.Rconv(i)] = int16(i)
478
	}
479
	for i := mips.REG_F0; i <= mips.REG_F31; i++ {
480
		register[obj.Rconv(i)] = int16(i)
481
	}
482
	for i := mips.REG_M0; i <= mips.REG_M31; i++ {
483
		register[obj.Rconv(i)] = int16(i)
484
	}
485
	for i := mips.REG_FCR0; i <= mips.REG_FCR31; i++ {
486
		register[obj.Rconv(i)] = int16(i)
487
	}
488
	for i := mips.REG_W0; i <= mips.REG_W31; i++ {
489
		register[obj.Rconv(i)] = int16(i)
490
	}
491
	register["HI"] = mips.REG_HI
492
	register["LO"] = mips.REG_LO
493
	// Pseudo-registers.
494
	register["SB"] = RSB
495
	register["FP"] = RFP
496
	register["PC"] = RPC
497
	// Avoid unintentionally clobbering g using R30.
498
	delete(register, "R30")
499
	register["g"] = mips.REG_R30
500
	// Avoid unintentionally clobbering RSB using R28.
501
	delete(register, "R28")
502
	register["RSB"] = mips.REG_R28
503
	registerPrefix := map[string]bool{
504
		"F":   true,
505
		"FCR": true,
506
		"M":   true,
507
		"R":   true,
508
		"W":   true,
509
	}
510

511
	instructions := make(map[string]obj.As)
512
	for i, s := range obj.Anames {
513
		instructions[s] = obj.As(i)
514
	}
515
	for i, s := range mips.Anames {
516
		if obj.As(i) >= obj.A_ARCHSPECIFIC {
517
			instructions[s] = obj.As(i) + obj.ABaseMIPS
518
		}
519
	}
520
	// Annoying alias.
521
	instructions["JAL"] = mips.AJAL
522

523
	return &Arch{
524
		LinkArch:       linkArch,
525
		Instructions:   instructions,
526
		Register:       register,
527
		RegisterPrefix: registerPrefix,
528
		RegisterNumber: mipsRegisterNumber,
529
		IsJump:         jumpMIPS,
530
	}
531
}
532

533
func archRISCV64() *Arch {
534
	register := make(map[string]int16)
535

536
	// Standard register names.
537
	for i := riscv.REG_X0; i <= riscv.REG_X31; i++ {
538
		name := fmt.Sprintf("X%d", i-riscv.REG_X0)
539
		register[name] = int16(i)
540
	}
541
	for i := riscv.REG_F0; i <= riscv.REG_F31; i++ {
542
		name := fmt.Sprintf("F%d", i-riscv.REG_F0)
543
		register[name] = int16(i)
544
	}
545

546
	// General registers with ABI names.
547
	register["ZERO"] = riscv.REG_ZERO
548
	register["RA"] = riscv.REG_RA
549
	register["SP"] = riscv.REG_SP
550
	register["GP"] = riscv.REG_GP
551
	register["TP"] = riscv.REG_TP
552
	register["T0"] = riscv.REG_T0
553
	register["T1"] = riscv.REG_T1
554
	register["T2"] = riscv.REG_T2
555
	register["S0"] = riscv.REG_S0
556
	register["S1"] = riscv.REG_S1
557
	register["A0"] = riscv.REG_A0
558
	register["A1"] = riscv.REG_A1
559
	register["A2"] = riscv.REG_A2
560
	register["A3"] = riscv.REG_A3
561
	register["A4"] = riscv.REG_A4
562
	register["A5"] = riscv.REG_A5
563
	register["A6"] = riscv.REG_A6
564
	register["A7"] = riscv.REG_A7
565
	register["S2"] = riscv.REG_S2
566
	register["S3"] = riscv.REG_S3
567
	register["S4"] = riscv.REG_S4
568
	register["S5"] = riscv.REG_S5
569
	register["S6"] = riscv.REG_S6
570
	register["S7"] = riscv.REG_S7
571
	register["S8"] = riscv.REG_S8
572
	register["S9"] = riscv.REG_S9
573
	register["S10"] = riscv.REG_S10
574
	register["S11"] = riscv.REG_S11
575
	register["T3"] = riscv.REG_T3
576
	register["T4"] = riscv.REG_T4
577
	register["T5"] = riscv.REG_T5
578
	register["T6"] = riscv.REG_T6
579

580
	// Go runtime register names.
581
	register["g"] = riscv.REG_G
582
	register["CTXT"] = riscv.REG_CTXT
583
	register["TMP"] = riscv.REG_TMP
584

585
	// ABI names for floating point register.
586
	register["FT0"] = riscv.REG_FT0
587
	register["FT1"] = riscv.REG_FT1
588
	register["FT2"] = riscv.REG_FT2
589
	register["FT3"] = riscv.REG_FT3
590
	register["FT4"] = riscv.REG_FT4
591
	register["FT5"] = riscv.REG_FT5
592
	register["FT6"] = riscv.REG_FT6
593
	register["FT7"] = riscv.REG_FT7
594
	register["FS0"] = riscv.REG_FS0
595
	register["FS1"] = riscv.REG_FS1
596
	register["FA0"] = riscv.REG_FA0
597
	register["FA1"] = riscv.REG_FA1
598
	register["FA2"] = riscv.REG_FA2
599
	register["FA3"] = riscv.REG_FA3
600
	register["FA4"] = riscv.REG_FA4
601
	register["FA5"] = riscv.REG_FA5
602
	register["FA6"] = riscv.REG_FA6
603
	register["FA7"] = riscv.REG_FA7
604
	register["FS2"] = riscv.REG_FS2
605
	register["FS3"] = riscv.REG_FS3
606
	register["FS4"] = riscv.REG_FS4
607
	register["FS5"] = riscv.REG_FS5
608
	register["FS6"] = riscv.REG_FS6
609
	register["FS7"] = riscv.REG_FS7
610
	register["FS8"] = riscv.REG_FS8
611
	register["FS9"] = riscv.REG_FS9
612
	register["FS10"] = riscv.REG_FS10
613
	register["FS11"] = riscv.REG_FS11
614
	register["FT8"] = riscv.REG_FT8
615
	register["FT9"] = riscv.REG_FT9
616
	register["FT10"] = riscv.REG_FT10
617
	register["FT11"] = riscv.REG_FT11
618

619
	// Pseudo-registers.
620
	register["SB"] = RSB
621
	register["FP"] = RFP
622
	register["PC"] = RPC
623

624
	instructions := make(map[string]obj.As)
625
	for i, s := range obj.Anames {
626
		instructions[s] = obj.As(i)
627
	}
628
	for i, s := range riscv.Anames {
629
		if obj.As(i) >= obj.A_ARCHSPECIFIC {
630
			instructions[s] = obj.As(i) + obj.ABaseRISCV
631
		}
632
	}
633

634
	return &Arch{
635
		LinkArch:       &riscv.LinkRISCV64,
636
		Instructions:   instructions,
637
		Register:       register,
638
		RegisterPrefix: nil,
639
		RegisterNumber: nilRegisterNumber,
640
		IsJump:         jumpRISCV,
641
	}
642
}
643

644
func archS390x() *Arch {
645
	register := 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.
648
	for i := s390x.REG_R0; i <= s390x.REG_R15; i++ {
649
		register[obj.Rconv(i)] = int16(i)
650
	}
651
	for i := s390x.REG_F0; i <= s390x.REG_F15; i++ {
652
		register[obj.Rconv(i)] = int16(i)
653
	}
654
	for i := s390x.REG_V0; i <= s390x.REG_V31; i++ {
655
		register[obj.Rconv(i)] = int16(i)
656
	}
657
	for i := s390x.REG_AR0; i <= s390x.REG_AR15; i++ {
658
		register[obj.Rconv(i)] = int16(i)
659
	}
660
	register["LR"] = s390x.REG_LR
661
	// Pseudo-registers.
662
	register["SB"] = RSB
663
	register["FP"] = RFP
664
	register["PC"] = RPC
665
	// Avoid unintentionally clobbering g using R13.
666
	delete(register, "R13")
667
	register["g"] = s390x.REG_R13
668
	registerPrefix := map[string]bool{
669
		"AR": true,
670
		"F":  true,
671
		"R":  true,
672
	}
673

674
	instructions := make(map[string]obj.As)
675
	for i, s := range obj.Anames {
676
		instructions[s] = obj.As(i)
677
	}
678
	for i, s := range s390x.Anames {
679
		if obj.As(i) >= obj.A_ARCHSPECIFIC {
680
			instructions[s] = obj.As(i) + obj.ABaseS390X
681
		}
682
	}
683
	// Annoying aliases.
684
	instructions["BR"] = s390x.ABR
685
	instructions["BL"] = s390x.ABL
686

687
	return &Arch{
688
		LinkArch:       &s390x.Links390x,
689
		Instructions:   instructions,
690
		Register:       register,
691
		RegisterPrefix: registerPrefix,
692
		RegisterNumber: s390xRegisterNumber,
693
		IsJump:         jumpS390x,
694
	}
695
}
696

697
func archWasm() *Arch {
698
	instructions := make(map[string]obj.As)
699
	for i, s := range obj.Anames {
700
		instructions[s] = obj.As(i)
701
	}
702
	for i, s := range wasm.Anames {
703
		if obj.As(i) >= obj.A_ARCHSPECIFIC {
704
			instructions[s] = obj.As(i) + obj.ABaseWasm
705
		}
706
	}
707

708
	return &Arch{
709
		LinkArch:       &wasm.Linkwasm,
710
		Instructions:   instructions,
711
		Register:       wasm.Register,
712
		RegisterPrefix: nil,
713
		RegisterNumber: nilRegisterNumber,
714
		IsJump:         jumpWasm,
715
	}
716
}
717

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.