-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patharm64.go
111 lines (100 loc) · 3.03 KB
/
arm64.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package asmgen
var ArchARM64 = &Arch{
Name: "arm64",
WordBits: 64,
WordBytes: 8,
CarrySafeLoop: true,
regs: []string{
// R18 is the platform register.
// R27 is the assembler/linker temporary (which we could potentially use but don't).
// R28 is g.
// R29 is FP.
// R30 is LR.
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9",
"R10", "R11", "R12", "R13", "R14", "R15", "R16", "R17", "R19",
"R20", "R21", "R22", "R23", "R24", "R25", "R26",
},
reg0: "ZR",
mov: "MOVD",
add: "ADD",
adds: "ADDS",
adc: "ADC",
adcs: "ADCS",
sub: "SUB",
subs: "SUBS",
sbc: "SBC",
sbcs: "SBCS",
mul: "MUL",
mulhi: "UMULH",
lsh: "LSL",
rsh: "LSR",
and: "AND",
or: "ORR",
xor: "EOR",
addWords: "ADD %[1]s<<3, %[2]s, %[3]s",
jmpZero: "CBZ %s, %s",
jmpNonZero: "CBNZ %s, %s",
loadIncN: arm64LoadIncN,
loadDecN: arm64LoadDecN,
storeIncN: arm64StoreIncN,
storeDecN: arm64StoreDecN,
}
func arm64LoadIncN(a *Asm, p RegPtr, regs []Reg) {
if len(regs) == 1 {
a.Printf("\tMOVD.P %d(%s), %s\n", a.Arch.WordBytes, p, regs[0])
return
}
a.Printf("\tLDP.P %d(%s), (%s, %s)\n", len(regs)*a.Arch.WordBytes, p, regs[0], regs[1])
var i int
for i = 2; i+2 <= len(regs); i += 2 {
a.Printf("\tLDP %d(%s), (%s, %s)\n", (i-len(regs))*a.Arch.WordBytes, p, regs[i], regs[i+1])
}
if i < len(regs) {
a.Printf("\tMOVD %d(%s), %s\n", -1*a.Arch.WordBytes, p, regs[i])
}
}
func arm64LoadDecN(a *Asm, p RegPtr, regs []Reg) {
if len(regs) == 1 {
a.Printf("\tMOVD.W -%d(%s), %s\n", a.Arch.WordBytes, p, regs[0])
return
}
a.Printf("\tLDP.W %d(%s), (%s, %s)\n", -len(regs)*a.Arch.WordBytes, p, regs[len(regs)-1], regs[len(regs)-2])
var i int
for i = 2; i+2 <= len(regs); i += 2 {
a.Printf("\tLDP %d(%s), (%s, %s)\n", i*a.Arch.WordBytes, p, regs[len(regs)-1-i], regs[len(regs)-2-i])
}
if i < len(regs) {
a.Printf("\tMOVD %d(%s), %s\n", i*a.Arch.WordBytes, p, regs[0])
}
}
func arm64StoreIncN(a *Asm, p RegPtr, regs []Reg) {
if len(regs) == 1 {
a.Printf("\tMOVD.P %s, %d(%s)\n", regs[0], a.Arch.WordBytes, p)
return
}
a.Printf("\tSTP.P (%s, %s), %d(%s)\n", regs[0], regs[1], len(regs)*a.Arch.WordBytes, p)
var i int
for i = 2; i+2 <= len(regs); i += 2 {
a.Printf("\tSTP (%s, %s), %d(%s)\n", regs[i], regs[i+1], (i-len(regs))*a.Arch.WordBytes, p)
}
if i < len(regs) {
a.Printf("\tMOVD %s, %d(%s)\n", regs[i], -1*a.Arch.WordBytes, p)
}
}
func arm64StoreDecN(a *Asm, p RegPtr, regs []Reg) {
if len(regs) == 1 {
a.Printf("\tMOVD.W %s, -%d(%s)\n", regs[0], a.Arch.WordBytes, p)
return
}
a.Printf("\tSTP.W (%s, %s), %d(%s)\n", regs[len(regs)-1], regs[len(regs)-2], -len(regs)*a.Arch.WordBytes, p)
var i int
for i = 2; i+2 <= len(regs); i += 2 {
a.Printf("\tSTP (%s, %s), %d(%s)\n", regs[len(regs)-1-i], regs[len(regs)-2-i], i*a.Arch.WordBytes, p)
}
if i < len(regs) {
a.Printf("\tMOVD %s, %d(%s)\n", regs[0], i*a.Arch.WordBytes, p)
}
}