1
2
3
4
5 package armasm
6
7 import (
8 "bytes"
9 "fmt"
10 )
11
12
13 type Mode int
14
15 const (
16 _ Mode = iota
17 ModeARM
18 ModeThumb
19 )
20
21 func (m Mode) String() string {
22 switch m {
23 case ModeARM:
24 return "ARM"
25 case ModeThumb:
26 return "Thumb"
27 }
28 return fmt.Sprintf("Mode(%d)", int(m))
29 }
30
31
32 type Op uint16
33
34
35
36
37
38
39 func (op Op) String() string {
40 if op >= Op(len(opstr)) || opstr[op] == "" {
41 return fmt.Sprintf("Op(%d)", int(op))
42 }
43 return opstr[op]
44 }
45
46
47 type Inst struct {
48 Op Op
49 Enc uint32
50 Len int
51 Args Args
52 }
53
54 func (i Inst) String() string {
55 var buf bytes.Buffer
56 buf.WriteString(i.Op.String())
57 for j, arg := range i.Args {
58 if arg == nil {
59 break
60 }
61 if j == 0 {
62 buf.WriteString(" ")
63 } else {
64 buf.WriteString(", ")
65 }
66 buf.WriteString(arg.String())
67 }
68 return buf.String()
69 }
70
71
72
73
74 type Args [4]Arg
75
76
77
78 type Arg interface {
79 IsArg()
80 String() string
81 }
82
83 type Float32Imm float32
84
85 func (Float32Imm) IsArg() {}
86
87 func (f Float32Imm) String() string {
88 return fmt.Sprintf("#%v", float32(f))
89 }
90
91 type Float64Imm float32
92
93 func (Float64Imm) IsArg() {}
94
95 func (f Float64Imm) String() string {
96 return fmt.Sprintf("#%v", float64(f))
97 }
98
99
100 type Imm uint32
101
102 func (Imm) IsArg() {}
103
104 func (i Imm) String() string {
105 return fmt.Sprintf("#%#x", uint32(i))
106 }
107
108
109 type ImmAlt struct {
110 Val uint8
111 Rot uint8
112 }
113
114 func (ImmAlt) IsArg() {}
115
116 func (i ImmAlt) Imm() Imm {
117 v := uint32(i.Val)
118 r := uint(i.Rot)
119 return Imm(v>>r | v<<(32-r))
120 }
121
122 func (i ImmAlt) String() string {
123 return fmt.Sprintf("#%#x, %d", i.Val, i.Rot)
124 }
125
126
127 type Label uint32
128
129 func (Label) IsArg() {}
130
131 func (i Label) String() string {
132 return fmt.Sprintf("%#x", uint32(i))
133 }
134
135
136
137 type Reg uint8
138
139 const (
140 R0 Reg = iota
141 R1
142 R2
143 R3
144 R4
145 R5
146 R6
147 R7
148 R8
149 R9
150 R10
151 R11
152 R12
153 R13
154 R14
155 R15
156
157 S0
158 S1
159 S2
160 S3
161 S4
162 S5
163 S6
164 S7
165 S8
166 S9
167 S10
168 S11
169 S12
170 S13
171 S14
172 S15
173 S16
174 S17
175 S18
176 S19
177 S20
178 S21
179 S22
180 S23
181 S24
182 S25
183 S26
184 S27
185 S28
186 S29
187 S30
188 S31
189
190 D0
191 D1
192 D2
193 D3
194 D4
195 D5
196 D6
197 D7
198 D8
199 D9
200 D10
201 D11
202 D12
203 D13
204 D14
205 D15
206 D16
207 D17
208 D18
209 D19
210 D20
211 D21
212 D22
213 D23
214 D24
215 D25
216 D26
217 D27
218 D28
219 D29
220 D30
221 D31
222
223 APSR
224 APSR_nzcv
225 FPSCR
226
227 SP = R13
228 LR = R14
229 PC = R15
230 )
231
232 func (Reg) IsArg() {}
233
234 func (r Reg) String() string {
235 switch r {
236 case APSR:
237 return "APSR"
238 case APSR_nzcv:
239 return "APSR_nzcv"
240 case FPSCR:
241 return "FPSCR"
242 case SP:
243 return "SP"
244 case PC:
245 return "PC"
246 case LR:
247 return "LR"
248 }
249 if R0 <= r && r <= R15 {
250 return fmt.Sprintf("R%d", int(r-R0))
251 }
252 if S0 <= r && r <= S31 {
253 return fmt.Sprintf("S%d", int(r-S0))
254 }
255 if D0 <= r && r <= D31 {
256 return fmt.Sprintf("D%d", int(r-D0))
257 }
258 return fmt.Sprintf("Reg(%d)", int(r))
259 }
260
261
262
263
264
265
266
267 type RegX struct {
268 Reg Reg
269 Index int
270 }
271
272 func (RegX) IsArg() {}
273
274 func (r RegX) String() string {
275 return fmt.Sprintf("%s[%d]", r.Reg, r.Index)
276 }
277
278
279
280 type RegList uint16
281
282 func (RegList) IsArg() {}
283
284 func (r RegList) String() string {
285 var buf bytes.Buffer
286 fmt.Fprintf(&buf, "{")
287 sep := ""
288 for i := 0; i < 16; i++ {
289 if r&(1<<uint(i)) != 0 {
290 fmt.Fprintf(&buf, "%s%s", sep, Reg(i).String())
291 sep = ","
292 }
293 }
294 fmt.Fprintf(&buf, "}")
295 return buf.String()
296 }
297
298
299 type Endian uint8
300
301 const (
302 LittleEndian Endian = 0
303 BigEndian Endian = 1
304 )
305
306 func (Endian) IsArg() {}
307
308 func (e Endian) String() string {
309 if e != 0 {
310 return "BE"
311 }
312 return "LE"
313 }
314
315
316 type Shift uint8
317
318 const (
319 ShiftLeft Shift = 0
320 ShiftRight Shift = 1
321 ShiftRightSigned Shift = 2
322 RotateRight Shift = 3
323 RotateRightExt Shift = 4
324 )
325
326 var shiftName = [...]string{
327 "LSL", "LSR", "ASR", "ROR", "RRX",
328 }
329
330 func (s Shift) String() string {
331 if s < 5 {
332 return shiftName[s]
333 }
334 return fmt.Sprintf("Shift(%d)", int(s))
335 }
336
337
338 type RegShift struct {
339 Reg Reg
340 Shift Shift
341 Count uint8
342 }
343
344 func (RegShift) IsArg() {}
345
346 func (r RegShift) String() string {
347 return fmt.Sprintf("%s %s #%d", r.Reg, r.Shift, r.Count)
348 }
349
350
351 type RegShiftReg struct {
352 Reg Reg
353 Shift Shift
354 RegCount Reg
355 }
356
357 func (RegShiftReg) IsArg() {}
358
359 func (r RegShiftReg) String() string {
360 return fmt.Sprintf("%s %s %s", r.Reg, r.Shift, r.RegCount)
361 }
362
363
364
365
366 type PCRel int32
367
368 func (PCRel) IsArg() {}
369
370 func (r PCRel) String() string {
371 return fmt.Sprintf("PC%+#x", int32(r))
372 }
373
374
375 type AddrMode uint8
376
377 const (
378 _ AddrMode = iota
379 AddrPostIndex
380 AddrPreIndex
381 AddrOffset
382 AddrLDM
383 AddrLDM_WB
384 )
385
386
387
388
389
390 type Mem struct {
391 Base Reg
392 Mode AddrMode
393 Sign int8
394 Index Reg
395 Shift Shift
396 Count uint8
397 Offset int16
398 }
399
400 func (Mem) IsArg() {}
401
402 func (m Mem) String() string {
403 R := m.Base.String()
404 X := ""
405 if m.Sign != 0 {
406 X = "+"
407 if m.Sign < 0 {
408 X = "-"
409 }
410 X += m.Index.String()
411 if m.Shift != ShiftLeft || m.Count != 0 {
412 X += fmt.Sprintf(", %s #%d", m.Shift, m.Count)
413 }
414 } else {
415 X = fmt.Sprintf("#%d", m.Offset)
416 }
417
418 switch m.Mode {
419 case AddrOffset:
420 if X == "#0" {
421 return fmt.Sprintf("[%s]", R)
422 }
423 return fmt.Sprintf("[%s, %s]", R, X)
424 case AddrPreIndex:
425 return fmt.Sprintf("[%s, %s]!", R, X)
426 case AddrPostIndex:
427 return fmt.Sprintf("[%s], %s", R, X)
428 case AddrLDM:
429 if X == "#0" {
430 return R
431 }
432 case AddrLDM_WB:
433 if X == "#0" {
434 return R + "!"
435 }
436 }
437 return fmt.Sprintf("[%s Mode(%d) %s]", R, int(m.Mode), X)
438 }
439
View as plain text