Source file src/pkg/cmd/vendor/golang.org/x/arch/arm/armasm/decode.go
1
2
3
4
5 package armasm
6
7 import (
8 "encoding/binary"
9 "fmt"
10 )
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 type instFormat struct {
26 mask uint32
27 value uint32
28 priority int8
29 op Op
30 opBits uint64
31 args instArgs
32 }
33
34 type instArgs [4]instArg
35
36 var (
37 errMode = fmt.Errorf("unsupported execution mode")
38 errShort = fmt.Errorf("truncated instruction")
39 errUnknown = fmt.Errorf("unknown instruction")
40 )
41
42 var decoderCover []bool
43
44
45 func Decode(src []byte, mode Mode) (inst Inst, err error) {
46 if mode != ModeARM {
47 return Inst{}, errMode
48 }
49 if len(src) < 4 {
50 return Inst{}, errShort
51 }
52
53 if decoderCover == nil {
54 decoderCover = make([]bool, len(instFormats))
55 }
56
57 x := binary.LittleEndian.Uint32(src)
58
59
60
61
62
63
64 const condMask = 0xf0000000
65 xNoCond := x
66 if x&condMask != condMask {
67 xNoCond &^= condMask
68 }
69 var priority int8
70 Search:
71 for i := range instFormats {
72 f := &instFormats[i]
73 if xNoCond&(f.mask|condMask) != f.value || f.priority <= priority {
74 continue
75 }
76 delta := uint32(0)
77 deltaShift := uint(0)
78 for opBits := f.opBits; opBits != 0; opBits >>= 16 {
79 n := uint(opBits & 0xFF)
80 off := uint((opBits >> 8) & 0xFF)
81 delta |= (x >> off) & (1<<n - 1) << deltaShift
82 deltaShift += n
83 }
84 op := f.op + Op(delta)
85
86
87 if op&^15 == BKPT_EQ && op != BKPT {
88 continue Search
89 }
90
91 var args Args
92 for j, aop := range f.args {
93 if aop == 0 {
94 break
95 }
96 arg := decodeArg(aop, x)
97 if arg == nil {
98 continue Search
99 }
100 args[j] = arg
101 }
102
103 decoderCover[i] = true
104
105 inst = Inst{
106 Op: op,
107 Args: args,
108 Enc: x,
109 Len: 4,
110 }
111 priority = f.priority
112 continue Search
113 }
114 if inst.Op != 0 {
115 return inst, nil
116 }
117 return Inst{}, errUnknown
118 }
119
120
121
122
123
124
125
126
127 type instArg uint8
128
129 const (
130 _ instArg = iota
131 arg_APSR
132 arg_FPSCR
133 arg_Dn_half
134 arg_R1_0
135 arg_R1_12
136 arg_R2_0
137 arg_R2_12
138 arg_R_0
139 arg_R_12
140 arg_R_12_nzcv
141 arg_R_16
142 arg_R_16_WB
143 arg_R_8
144 arg_R_rotate
145 arg_R_shift_R
146 arg_R_shift_imm
147 arg_SP
148 arg_Sd
149 arg_Sd_Dd
150 arg_Dd_Sd
151 arg_Sm
152 arg_Sm_Dm
153 arg_Sn
154 arg_Sn_Dn
155 arg_const
156 arg_endian
157 arg_fbits
158 arg_fp_0
159 arg_imm24
160 arg_imm5
161 arg_imm5_32
162 arg_imm5_nz
163 arg_imm_12at8_4at0
164 arg_imm_4at16_12at0
165 arg_imm_vfp
166 arg_label24
167 arg_label24H
168 arg_label_m_12
169 arg_label_p_12
170 arg_label_pm_12
171 arg_label_pm_4_4
172 arg_lsb_width
173 arg_mem_R
174 arg_mem_R_pm_R_W
175 arg_mem_R_pm_R_postindex
176 arg_mem_R_pm_R_shift_imm_W
177 arg_mem_R_pm_R_shift_imm_offset
178 arg_mem_R_pm_R_shift_imm_postindex
179 arg_mem_R_pm_imm12_W
180 arg_mem_R_pm_imm12_offset
181 arg_mem_R_pm_imm12_postindex
182 arg_mem_R_pm_imm8_W
183 arg_mem_R_pm_imm8_postindex
184 arg_mem_R_pm_imm8at0_offset
185 arg_option
186 arg_registers
187 arg_registers1
188 arg_registers2
189 arg_satimm4
190 arg_satimm5
191 arg_satimm4m1
192 arg_satimm5m1
193 arg_widthm1
194 )
195
196
197
198 func decodeArg(aop instArg, x uint32) Arg {
199 switch aop {
200 default:
201 return nil
202
203 case arg_APSR:
204 return APSR
205 case arg_FPSCR:
206 return FPSCR
207
208 case arg_R_0:
209 return Reg(x & (1<<4 - 1))
210 case arg_R_8:
211 return Reg((x >> 8) & (1<<4 - 1))
212 case arg_R_12:
213 return Reg((x >> 12) & (1<<4 - 1))
214 case arg_R_16:
215 return Reg((x >> 16) & (1<<4 - 1))
216
217 case arg_R_12_nzcv:
218 r := Reg((x >> 12) & (1<<4 - 1))
219 if r == R15 {
220 return APSR_nzcv
221 }
222 return r
223
224 case arg_R_16_WB:
225 mode := AddrLDM
226 if (x>>21)&1 != 0 {
227 mode = AddrLDM_WB
228 }
229 return Mem{Base: Reg((x >> 16) & (1<<4 - 1)), Mode: mode}
230
231 case arg_R_rotate:
232 Rm := Reg(x & (1<<4 - 1))
233 typ, count := decodeShift(x)
234
235 if typ == RotateRightExt {
236 return Reg(Rm)
237 }
238 return RegShift{Rm, typ, uint8(count)}
239
240 case arg_R_shift_R:
241 Rm := Reg(x & (1<<4 - 1))
242 Rs := Reg((x >> 8) & (1<<4 - 1))
243 typ := Shift((x >> 5) & (1<<2 - 1))
244 return RegShiftReg{Rm, typ, Rs}
245
246 case arg_R_shift_imm:
247 Rm := Reg(x & (1<<4 - 1))
248 typ, count := decodeShift(x)
249 if typ == ShiftLeft && count == 0 {
250 return Reg(Rm)
251 }
252 return RegShift{Rm, typ, uint8(count)}
253
254 case arg_R1_0:
255 return Reg((x & (1<<4 - 1)))
256 case arg_R1_12:
257 return Reg(((x >> 12) & (1<<4 - 1)))
258 case arg_R2_0:
259 return Reg((x & (1<<4 - 1)) | 1)
260 case arg_R2_12:
261 return Reg(((x >> 12) & (1<<4 - 1)) | 1)
262
263 case arg_SP:
264 return SP
265
266 case arg_Sd_Dd:
267 v := (x >> 12) & (1<<4 - 1)
268 vx := (x >> 22) & 1
269 sz := (x >> 8) & 1
270 if sz != 0 {
271 return D0 + Reg(vx<<4+v)
272 } else {
273 return S0 + Reg(v<<1+vx)
274 }
275
276 case arg_Dd_Sd:
277 return decodeArg(arg_Sd_Dd, x^(1<<8))
278
279 case arg_Sd:
280 v := (x >> 12) & (1<<4 - 1)
281 vx := (x >> 22) & 1
282 return S0 + Reg(v<<1+vx)
283
284 case arg_Sm_Dm:
285 v := (x >> 0) & (1<<4 - 1)
286 vx := (x >> 5) & 1
287 sz := (x >> 8) & 1
288 if sz != 0 {
289 return D0 + Reg(vx<<4+v)
290 } else {
291 return S0 + Reg(v<<1+vx)
292 }
293
294 case arg_Sm:
295 v := (x >> 0) & (1<<4 - 1)
296 vx := (x >> 5) & 1
297 return S0 + Reg(v<<1+vx)
298
299 case arg_Dn_half:
300 v := (x >> 16) & (1<<4 - 1)
301 vx := (x >> 7) & 1
302 return RegX{D0 + Reg(vx<<4+v), int((x >> 21) & 1)}
303
304 case arg_Sn_Dn:
305 v := (x >> 16) & (1<<4 - 1)
306 vx := (x >> 7) & 1
307 sz := (x >> 8) & 1
308 if sz != 0 {
309 return D0 + Reg(vx<<4+v)
310 } else {
311 return S0 + Reg(v<<1+vx)
312 }
313
314 case arg_Sn:
315 v := (x >> 16) & (1<<4 - 1)
316 vx := (x >> 7) & 1
317 return S0 + Reg(v<<1+vx)
318
319 case arg_const:
320 v := x & (1<<8 - 1)
321 rot := (x >> 8) & (1<<4 - 1) * 2
322 if rot > 0 && v&3 == 0 {
323
324 return ImmAlt{uint8(v), uint8(rot)}
325 }
326 if rot >= 24 && ((v<<(32-rot))&0xFF)>>(32-rot) == v {
327
328 return ImmAlt{uint8(v), uint8(rot)}
329 }
330 return Imm(v>>rot | v<<(32-rot))
331
332 case arg_endian:
333 return Endian((x >> 9) & 1)
334
335 case arg_fbits:
336 return Imm((16 << ((x >> 7) & 1)) - ((x&(1<<4-1))<<1 | (x>>5)&1))
337
338 case arg_fp_0:
339 return Imm(0)
340
341 case arg_imm24:
342 return Imm(x & (1<<24 - 1))
343
344 case arg_imm5:
345 return Imm((x >> 7) & (1<<5 - 1))
346
347 case arg_imm5_32:
348 x = (x >> 7) & (1<<5 - 1)
349 if x == 0 {
350 x = 32
351 }
352 return Imm(x)
353
354 case arg_imm5_nz:
355 x = (x >> 7) & (1<<5 - 1)
356 if x == 0 {
357 return nil
358 }
359 return Imm(x)
360
361 case arg_imm_4at16_12at0:
362 return Imm((x>>16)&(1<<4-1)<<12 | x&(1<<12-1))
363
364 case arg_imm_12at8_4at0:
365 return Imm((x>>8)&(1<<12-1)<<4 | x&(1<<4-1))
366
367 case arg_imm_vfp:
368 x = (x>>16)&(1<<4-1)<<4 | x&(1<<4-1)
369 return Imm(x)
370
371 case arg_label24:
372 imm := (x & (1<<24 - 1)) << 2
373 return PCRel(int32(imm<<6) >> 6)
374
375 case arg_label24H:
376 h := (x >> 24) & 1
377 imm := (x&(1<<24-1))<<2 | h<<1
378 return PCRel(int32(imm<<6) >> 6)
379
380 case arg_label_m_12:
381 d := int32(x & (1<<12 - 1))
382 return Mem{Base: PC, Mode: AddrOffset, Offset: int16(-d)}
383
384 case arg_label_p_12:
385 d := int32(x & (1<<12 - 1))
386 return Mem{Base: PC, Mode: AddrOffset, Offset: int16(d)}
387
388 case arg_label_pm_12:
389 d := int32(x & (1<<12 - 1))
390 u := (x >> 23) & 1
391 if u == 0 {
392 d = -d
393 }
394 return Mem{Base: PC, Mode: AddrOffset, Offset: int16(d)}
395
396 case arg_label_pm_4_4:
397 d := int32((x>>8)&(1<<4-1)<<4 | x&(1<<4-1))
398 u := (x >> 23) & 1
399 if u == 0 {
400 d = -d
401 }
402 return PCRel(d)
403
404 case arg_lsb_width:
405 lsb := (x >> 7) & (1<<5 - 1)
406 msb := (x >> 16) & (1<<5 - 1)
407 if msb < lsb || msb >= 32 {
408 return nil
409 }
410 return Imm(msb + 1 - lsb)
411
412 case arg_mem_R:
413 Rn := Reg((x >> 16) & (1<<4 - 1))
414 return Mem{Base: Rn, Mode: AddrOffset}
415
416 case arg_mem_R_pm_R_postindex:
417
418
419 return decodeArg(arg_mem_R_pm_R_shift_imm_W, x&^((1<<7-1)<<5|1<<24|1<<21))
420
421 case arg_mem_R_pm_R_W:
422
423
424 return decodeArg(arg_mem_R_pm_R_shift_imm_W, x&^((1<<7-1)<<5))
425
426 case arg_mem_R_pm_R_shift_imm_offset:
427
428
429 return decodeArg(arg_mem_R_pm_R_shift_imm_W, x&^(1<<21)|1<<24)
430
431 case arg_mem_R_pm_R_shift_imm_postindex:
432
433
434 return decodeArg(arg_mem_R_pm_R_shift_imm_W, x&^(1<<24|1<<21))
435
436 case arg_mem_R_pm_R_shift_imm_W:
437 Rn := Reg((x >> 16) & (1<<4 - 1))
438 Rm := Reg(x & (1<<4 - 1))
439 typ, count := decodeShift(x)
440 u := (x >> 23) & 1
441 w := (x >> 21) & 1
442 p := (x >> 24) & 1
443 if p == 0 && w == 1 {
444 return nil
445 }
446 sign := int8(+1)
447 if u == 0 {
448 sign = -1
449 }
450 mode := AddrMode(uint8(p<<1) | uint8(w^1))
451 return Mem{Base: Rn, Mode: mode, Sign: sign, Index: Rm, Shift: typ, Count: count}
452
453 case arg_mem_R_pm_imm12_offset:
454
455
456 return decodeArg(arg_mem_R_pm_imm12_W, x&^(1<<21)|1<<24)
457
458 case arg_mem_R_pm_imm12_postindex:
459
460
461 return decodeArg(arg_mem_R_pm_imm12_W, x&^(1<<24|1<<21))
462
463 case arg_mem_R_pm_imm12_W:
464 Rn := Reg((x >> 16) & (1<<4 - 1))
465 u := (x >> 23) & 1
466 w := (x >> 21) & 1
467 p := (x >> 24) & 1
468 if p == 0 && w == 1 {
469 return nil
470 }
471 sign := int8(+1)
472 if u == 0 {
473 sign = -1
474 }
475 imm := int16(x & (1<<12 - 1))
476 mode := AddrMode(uint8(p<<1) | uint8(w^1))
477 return Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm}
478
479 case arg_mem_R_pm_imm8_postindex:
480
481
482 return decodeArg(arg_mem_R_pm_imm8_W, x&^(1<<24|1<<21))
483
484 case arg_mem_R_pm_imm8_W:
485 Rn := Reg((x >> 16) & (1<<4 - 1))
486 u := (x >> 23) & 1
487 w := (x >> 21) & 1
488 p := (x >> 24) & 1
489 if p == 0 && w == 1 {
490 return nil
491 }
492 sign := int8(+1)
493 if u == 0 {
494 sign = -1
495 }
496 imm := int16((x>>8)&(1<<4-1)<<4 | x&(1<<4-1))
497 mode := AddrMode(uint8(p<<1) | uint8(w^1))
498 return Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm}
499
500 case arg_mem_R_pm_imm8at0_offset:
501 Rn := Reg((x >> 16) & (1<<4 - 1))
502 u := (x >> 23) & 1
503 sign := int8(+1)
504 if u == 0 {
505 sign = -1
506 }
507 imm := int16(x&(1<<8-1)) << 2
508 return Mem{Base: Rn, Mode: AddrOffset, Offset: int16(sign) * imm}
509
510 case arg_option:
511 return Imm(x & (1<<4 - 1))
512
513 case arg_registers:
514 return RegList(x & (1<<16 - 1))
515
516 case arg_registers2:
517 x &= 1<<16 - 1
518 n := 0
519 for i := 0; i < 16; i++ {
520 if x>>uint(i)&1 != 0 {
521 n++
522 }
523 }
524 if n < 2 {
525 return nil
526 }
527 return RegList(x)
528
529 case arg_registers1:
530 Rt := (x >> 12) & (1<<4 - 1)
531 return RegList(1 << Rt)
532
533 case arg_satimm4:
534 return Imm((x >> 16) & (1<<4 - 1))
535
536 case arg_satimm5:
537 return Imm((x >> 16) & (1<<5 - 1))
538
539 case arg_satimm4m1:
540 return Imm((x>>16)&(1<<4-1) + 1)
541
542 case arg_satimm5m1:
543 return Imm((x>>16)&(1<<5-1) + 1)
544
545 case arg_widthm1:
546 return Imm((x>>16)&(1<<5-1) + 1)
547
548 }
549 }
550
551
552 func decodeShift(x uint32) (Shift, uint8) {
553 count := (x >> 7) & (1<<5 - 1)
554 typ := Shift((x >> 5) & (1<<2 - 1))
555 switch typ {
556 case ShiftRight, ShiftRightSigned:
557 if count == 0 {
558 count = 32
559 }
560 case RotateRight:
561 if count == 0 {
562 typ = RotateRightExt
563 count = 1
564 }
565 }
566 return typ, uint8(count)
567 }
568
View as plain text