podman
288 строк · 6.8 Кб
1// cmd/7l/list.c and cmd/7l/sub.c from Vita Nuova.
2// https://code.google.com/p/ken-cc/source/browse/
3//
4// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
5// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
6// Portions Copyright © 1997-1999 Vita Nuova Limited
7// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
8// Portions Copyright © 2004,2006 Bruce Ellis
9// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
10// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
11// Portions Copyright © 2009 The Go Authors. All rights reserved.
12//
13// Permission is hereby granted, free of charge, to any person obtaining a copy
14// of this software and associated documentation files (the "Software"), to deal
15// in the Software without restriction, including without limitation the rights
16// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17// copies of the Software, and to permit persons to whom the Software is
18// furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included in
21// all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29// THE SOFTWARE.
30
31package arm64
32
33import (
34"github.com/twitchyliquid64/golang-asm/obj"
35"fmt"
36)
37
38var strcond = [16]string{
39"EQ",
40"NE",
41"HS",
42"LO",
43"MI",
44"PL",
45"VS",
46"VC",
47"HI",
48"LS",
49"GE",
50"LT",
51"GT",
52"LE",
53"AL",
54"NV",
55}
56
57func init() {
58obj.RegisterRegister(obj.RBaseARM64, REG_SPECIAL+1024, rconv)
59obj.RegisterOpcode(obj.ABaseARM64, Anames)
60obj.RegisterRegisterList(obj.RegListARM64Lo, obj.RegListARM64Hi, rlconv)
61obj.RegisterOpSuffix("arm64", obj.CConvARM)
62}
63
64func arrange(a int) string {
65switch a {
66case ARNG_8B:
67return "B8"
68case ARNG_16B:
69return "B16"
70case ARNG_4H:
71return "H4"
72case ARNG_8H:
73return "H8"
74case ARNG_2S:
75return "S2"
76case ARNG_4S:
77return "S4"
78case ARNG_1D:
79return "D1"
80case ARNG_2D:
81return "D2"
82case ARNG_B:
83return "B"
84case ARNG_H:
85return "H"
86case ARNG_S:
87return "S"
88case ARNG_D:
89return "D"
90case ARNG_1Q:
91return "Q1"
92default:
93return ""
94}
95}
96
97func rconv(r int) string {
98ext := (r >> 5) & 7
99if r == REGG {
100return "g"
101}
102switch {
103case REG_R0 <= r && r <= REG_R30:
104return fmt.Sprintf("R%d", r-REG_R0)
105case r == REG_R31:
106return "ZR"
107case REG_F0 <= r && r <= REG_F31:
108return fmt.Sprintf("F%d", r-REG_F0)
109case REG_V0 <= r && r <= REG_V31:
110return fmt.Sprintf("V%d", r-REG_V0)
111case COND_EQ <= r && r <= COND_NV:
112return strcond[r-COND_EQ]
113case r == REGSP:
114return "RSP"
115case r == REG_DAIFSet:
116return "DAIFSet"
117case r == REG_DAIFClr:
118return "DAIFClr"
119case r == REG_PLDL1KEEP:
120return "PLDL1KEEP"
121case r == REG_PLDL1STRM:
122return "PLDL1STRM"
123case r == REG_PLDL2KEEP:
124return "PLDL2KEEP"
125case r == REG_PLDL2STRM:
126return "PLDL2STRM"
127case r == REG_PLDL3KEEP:
128return "PLDL3KEEP"
129case r == REG_PLDL3STRM:
130return "PLDL3STRM"
131case r == REG_PLIL1KEEP:
132return "PLIL1KEEP"
133case r == REG_PLIL1STRM:
134return "PLIL1STRM"
135case r == REG_PLIL2KEEP:
136return "PLIL2KEEP"
137case r == REG_PLIL2STRM:
138return "PLIL2STRM"
139case r == REG_PLIL3KEEP:
140return "PLIL3KEEP"
141case r == REG_PLIL3STRM:
142return "PLIL3STRM"
143case r == REG_PSTL1KEEP:
144return "PSTL1KEEP"
145case r == REG_PSTL1STRM:
146return "PSTL1STRM"
147case r == REG_PSTL2KEEP:
148return "PSTL2KEEP"
149case r == REG_PSTL2STRM:
150return "PSTL2STRM"
151case r == REG_PSTL3KEEP:
152return "PSTL3KEEP"
153case r == REG_PSTL3STRM:
154return "PSTL3STRM"
155case REG_UXTB <= r && r < REG_UXTH:
156if ext != 0 {
157return fmt.Sprintf("%s.UXTB<<%d", regname(r), ext)
158} else {
159return fmt.Sprintf("%s.UXTB", regname(r))
160}
161case REG_UXTH <= r && r < REG_UXTW:
162if ext != 0 {
163return fmt.Sprintf("%s.UXTH<<%d", regname(r), ext)
164} else {
165return fmt.Sprintf("%s.UXTH", regname(r))
166}
167case REG_UXTW <= r && r < REG_UXTX:
168if ext != 0 {
169return fmt.Sprintf("%s.UXTW<<%d", regname(r), ext)
170} else {
171return fmt.Sprintf("%s.UXTW", regname(r))
172}
173case REG_UXTX <= r && r < REG_SXTB:
174if ext != 0 {
175return fmt.Sprintf("%s.UXTX<<%d", regname(r), ext)
176} else {
177return fmt.Sprintf("%s.UXTX", regname(r))
178}
179case REG_SXTB <= r && r < REG_SXTH:
180if ext != 0 {
181return fmt.Sprintf("%s.SXTB<<%d", regname(r), ext)
182} else {
183return fmt.Sprintf("%s.SXTB", regname(r))
184}
185case REG_SXTH <= r && r < REG_SXTW:
186if ext != 0 {
187return fmt.Sprintf("%s.SXTH<<%d", regname(r), ext)
188} else {
189return fmt.Sprintf("%s.SXTH", regname(r))
190}
191case REG_SXTW <= r && r < REG_SXTX:
192if ext != 0 {
193return fmt.Sprintf("%s.SXTW<<%d", regname(r), ext)
194} else {
195return fmt.Sprintf("%s.SXTW", regname(r))
196}
197case REG_SXTX <= r && r < REG_SPECIAL:
198if ext != 0 {
199return fmt.Sprintf("%s.SXTX<<%d", regname(r), ext)
200} else {
201return fmt.Sprintf("%s.SXTX", regname(r))
202}
203// bits 0-4 indicate register, bits 5-7 indicate shift amount, bit 8 equals to 0.
204case REG_LSL <= r && r < (REG_LSL+1<<8):
205return fmt.Sprintf("R%d<<%d", r&31, (r>>5)&7)
206case REG_ARNG <= r && r < REG_ELEM:
207return fmt.Sprintf("V%d.%s", r&31, arrange((r>>5)&15))
208case REG_ELEM <= r && r < REG_ELEM_END:
209return fmt.Sprintf("V%d.%s", r&31, arrange((r>>5)&15))
210}
211// Return system register name.
212name, _, _ := SysRegEnc(int16(r))
213if name != "" {
214return name
215}
216return fmt.Sprintf("badreg(%d)", r)
217}
218
219func DRconv(a int) string {
220if a >= C_NONE && a <= C_NCLASS {
221return cnames7[a]
222}
223return "C_??"
224}
225
226func rlconv(list int64) string {
227str := ""
228
229// ARM64 register list follows ARM64 instruction decode schema
230// | 31 | 30 | ... | 15 - 12 | 11 - 10 | ... |
231// +----+----+-----+---------+---------+-----+
232// | | Q | ... | opcode | size | ... |
233
234firstReg := int(list & 31)
235opcode := (list >> 12) & 15
236var regCnt int
237var t string
238switch opcode {
239case 0x7:
240regCnt = 1
241case 0xa:
242regCnt = 2
243case 0x6:
244regCnt = 3
245case 0x2:
246regCnt = 4
247default:
248regCnt = -1
249}
250// Q:size
251arng := ((list>>30)&1)<<2 | (list>>10)&3
252switch arng {
253case 0:
254t = "B8"
255case 4:
256t = "B16"
257case 1:
258t = "H4"
259case 5:
260t = "H8"
261case 2:
262t = "S2"
263case 6:
264t = "S4"
265case 3:
266t = "D1"
267case 7:
268t = "D2"
269}
270for i := 0; i < regCnt; i++ {
271if str == "" {
272str += "["
273} else {
274str += ","
275}
276str += fmt.Sprintf("V%d.", (firstReg+i)&31)
277str += t
278}
279str += "]"
280return str
281}
282
283func regname(r int) string {
284if r&31 == 31 {
285return "ZR"
286}
287return fmt.Sprintf("R%d", r&31)
288}
289