1 /*
2 * Common Development and Distribution License ("CDDL"), version 1.0.
3 * You may only use this file in accordance with the terms of version
4 * 1.0 of the CDDL.
5 *
6 * A full copy of the text of the CDDL should have accompanied this
7 * source. A copy of the CDDL is also available via the Internet at
8 * http://www.illumos.org/license/CDDL.
9 */
10 /*
11 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
12 * Copyright (c) 2015 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
13 */
14
15 /*
16 * This provides basic support for disassembling arm instructions. This is
17 * derived from the arm reference manual (generic), chapter A3 (ARM DDI 0100l).
18 * All instructions come in as uint32_t's.
19 */
20
21 #include <libdisasm.h>
22 #include <stdint.h>
23 #include <stdio.h>
24 #include <sys/byteorder.h>
25
26 #include "libdisasm_impl.h"
27
28 extern size_t strlen(const char *);
29 extern size_t strlcat(char *, const char *, size_t);
30
31 /*
32 * Condition code mask and shift, aka bits 28-31.
33 */
34 #define ARM_CC_MASK 0xf0000000
35 #define ARM_CC_SHIFT 28
36
37 /*
38 * First level of decoding, aka bits 25-27.
39 */
40 #define ARM_L1_DEC_MASK 0x0e000000
41 #define ARM_L1_DEC_SHIFT 25
42
43 /*
44 * Masks and values for the 0b000 l1 group
45 */
46 #define ARM_L1_0_B4_MASK 0x00000010
47 #define ARM_L1_0_B7_MASK 0x00000080
48 #define ARM_L1_0_OPMASK 0x01800000
49 #define ARM_L1_0_SPECOP 0x01000000
50 #define ARM_L1_0_SMASK 0x00100000
51 #define ARM_L1_0_ELS_MASK 0x00000060
52
53 /*
54 * Masks and values for the 0b001 l1 group.
55 */
56 #define ARM_L1_1_OPMASK 0x01800000
57 #define ARM_L1_1_SPECOP 0x01000000
58 #define ARM_L1_1_SMASK 0x00100000
59 #define ARM_L1_1_UNDEF_MASK 0x00200000
60
61 /*
62 * Masks and values for the 0b011 l1 group
63 */
64 #define ARM_L1_3_B4_MASK 0x00000010
65 #define ARM_L1_3_ARCHUN_MASK 0x01f000f0
66
67 /*
68 * Masks for the 0b111 l1 group
69 */
70 #define ARM_L1_7_COPROCMASK 0x00000010
71 #define ARM_L1_7_SWINTMASK 0x01000000
72
73 /*
74 * Masks for the data processing instructions (dpi)
75 */
76 #define ARM_DPI_OPCODE_MASK 0x01e00000
77 #define ARM_DPI_OPCODE_SHIFT 21
78 #define ARM_DPI_IBIT_MASK 0x02000000
79 #define ARM_DPI_SBIT_MASK 0x00100000
80 #define ARM_DPI_RN_MASK 0x000f0000
81 #define ARM_DPI_RN_SHIFT 16
82 #define ARM_DPI_RD_MASK 0x0000f000
83 #define ARM_DPI_RD_SHIFT 12
84 #define ARM_DPI_BIT4_MASK 0x00000010
85
86 #define ARM_DPI_IMM_ROT_MASK 0x00000f00
87 #define ARM_DPI_IMM_ROT_SHIFT 8
88 #define ARM_DPI_IMM_VAL_MASK 0x000000ff
89
90 #define ARM_DPI_IMS_SHIMM_MASK 0x00000f80
91 #define ARM_DPI_IMS_SHIMM_SHIFT 7
92 #define ARM_DPI_IMS_SHIFT_MASK 0x00000060
93 #define ARM_DPI_IMS_SHIFT_SHIFT 5
94 #define ARM_DPI_IMS_RM_MASK 0x0000000f
95
96 #define ARM_DPI_REGS_RS_MASK 0x00000f00
97 #define ARM_DPI_REGS_RS_SHIFT 8
98 #define ARM_DPI_REGS_SHIFT_MASK 0x00000060
99 #define ARM_DPI_REGS_SHIFT_SHIFT 5
100 #define ARM_DPI_REGS_RM_MASK 0x0000000f
101
102 /*
103 * Definitions for the word and byte LDR and STR instructions
104 */
105 #define ARM_LS_IBIT_MASK 0x02000000
106 #define ARM_LS_PBIT_MASK 0x01000000
107 #define ARM_LS_UBIT_MASK 0x00800000
108 #define ARM_LS_BBIT_MASK 0x00400000
109 #define ARM_LS_WBIT_MASK 0x00200000
110 #define ARM_LS_LBIT_MASK 0x00100000
111 #define ARM_LS_RN_MASK 0x000f0000
112 #define ARM_LS_RN_SHIFT 16
113 #define ARM_LS_RD_MASK 0x0000f000
114 #define ARM_LS_RD_SHIFT 12
115
116 #define ARM_LS_IMM_MASK 0x00000fff
117
118 #define ARM_LS_REG_RM_MASK 0x0000000f
119 #define ARM_LS_REG_NRM_MASK 0x00000ff0
120
121 #define ARM_LS_SCR_SIMM_MASK 0x00000f80
122 #define ARM_LS_SCR_SIMM_SHIFT 7
123 #define ARM_LS_SCR_SCODE_MASK 0x00000060
124 #define ARM_LS_SCR_SCODE_SHIFT 5
125 #define ARM_LS_SCR_RM_MASK 0x0000000f
126
127 /*
128 * Masks for the Load and Store multiple instructions.
129 */
130 #define ARM_LSM_PBIT_MASK 0x01000000
131 #define ARM_LSM_UBIT_MASK 0x00800000
132 #define ARM_LSM_SBIT_MASK 0x00400000
133 #define ARM_LSM_WBIT_MASK 0x00200000
134 #define ARM_LSM_LBIT_MASK 0x00100000
135 #define ARM_LSM_RN_MASK 0x000f0000
136 #define ARM_LSM_RN_SHIFT 16
137 #define ARM_LSM_RLIST_MASK 0x0000ffff
138 #define ARM_LSM_ADDR_MASK 0x01800000
139 #define ARM_LSM_ADDR_SHIFT 23
140
141 /*
142 * Masks for the Extended and Misc. Loads and stores. This is the extension
143 * space from figure A3-5. Most of them are handled by arm_dis_els() with the
144 * exception or swap / swap byte and load/store register exclusive which due to
145 * its nature is handled elsewhere.
146 */
147 #define ARM_ELS_SWAP_MASK 0x01b00000
148 #define ARM_ELS_SWAP_BYTE_MASK 0x00400000
149 #define ARM_ELS_IS_SWAP 0x01000000
150 #define ARM_ELS_EXCL_MASK 0x01800000
151 #define ARM_ELS_PBIT_MASK 0x01000000
152 #define ARM_ELS_UBIT_MASK 0x00800000
153 #define ARM_ELS_IBIT_MASK 0x00400000
154 #define ARM_ELS_WBIT_MASK 0x00200000
155 #define ARM_ELS_LBIT_MASK 0x00100000
156 #define ARM_ELS_SBIT_MASK 0x00000040
157 #define ARM_ELS_HBIT_MASK 0x00000020
158 #define ARM_ELS_RN_MASK 0x000f0000
159 #define ARM_ELS_RN_SHIFT 16
160 #define ARM_ELS_RD_MASK 0x0000f000
161 #define ARM_ELS_RD_SHIFT 12
162 #define ARM_ELS_UP_AM_MASK 0x00000f00
163 #define ARM_ELS_UP_AM_SHIFT 8
164 #define ARM_ELS_LOW_AM_MASK 0x0000000f
165
166 /*
167 * Multiply instruction extensino space masks and values
168 */
169 #define ARM_EMULT_UNBIT_MASK 0x00400000
170 #define ARM_EMULT_ABIT_MASK 0x00200000
171 #define ARM_EMULT_SBIT_MASK 0x00100000
172 #define ARM_EMULT_RD_MASK 0x000f0000
173 #define ARM_EMULT_RD_SHIFT 16
174 #define ARM_EMULT_RN_MASK 0x0000f000
175 #define ARM_EMULT_RN_SHIFT 12
176 #define ARM_EMULT_RS_MASK 0x00000f00
177 #define ARM_EMULT_RS_SHIFT 8
178 #define ARM_EMULT_RM_MASK 0x0000000f
179 #define ARM_EMULT_MA_MASK 0x0fc00000
180 #define ARM_EMULT_UMA_MASK 0x0ff00000
181 #define ARM_EMULT_UMA_TARG 0x00400000
182 #define ARM_EMULT_MAL_MASK 0x0f800000
183 #define ARM_EMULT_MAL_TARG 0x00800000
184
185 /*
186 * Here we have the masks and target values to indicate instructions from the
187 * Control and DSP extension space. There are a bunch of not quite related
188 * instructions, but that's okay. That's how this thing always rolls.
189 *
190 * The ARM_CDSP_STATUS_MASK and TARG do not catch the move immediate to status
191 * register. That's okay because they get handled and separated out in arm_dis.
192 */
193 #define ARM_CDSP_STATUS_MASK 0x0f9000f0
194 #define ARM_CDSP_STATUS_TARG 0x01000000
195 #define ARM_CDSP_BEX_UP_MASK 0x0ff00000 /* Branch/exchg/link instrs */
196 #define ARM_CDSP_BEX_UP_TARG 0x01200000
197 #define ARM_CDSP_BEX_LOW_MASK 0x000000f0
198 #define ARM_CDSP_BEX_NLOW_TARG 0x00000000 /* Here the target is inverse */
199 #define ARM_CDSP_CLZ_MASK 0x0ff000f0 /* Count leading zeros */
200 #define ARM_CDSP_CLZ_TARG 0x01200030
201 #define ARM_CDSP_SAT_MASK 0x0f9000f0 /* Saturating add/subtract */
202 #define ARM_CDSP_SAT_TARG 0x01000050
203 #define ARM_CDSP_BKPT_MASK 0x0ff000f0 /* Software breakpoint */
204 #define ARM_CDSP_BKPT_TARG 0x01200070
205 #define ARM_CDSP_SMUL_MASK 0x0f900090 /* Signed multiplies (type 2) */
206 #define ARM_CDSP_SMUL_TARG 0x01000080
207
208 #define ARM_CDSP_RN_MASK 0x000f0000
209 #define ARM_CDSP_RN_SHIFT 16
210 #define ARM_CDSP_RD_MASK 0x0000f000
211 #define ARM_CDSP_RD_SHIFT 12
212 #define ARM_CDSP_RS_MASK 0x00000f00
213 #define ARM_CDSP_RS_SHIFT 8
214 #define ARM_CDSP_RM_MASK 0x0000000f
215
216 #define ARM_CDSP_STATUS_RBIT 0x00400000
217 #define ARM_CDSP_MRS_MASK 0x00300000 /* Ditinguish MRS and MSR */
218 #define ARM_CDSP_MRS_TARG 0x00000000
219 #define ARM_CDSP_MSR_F_MASK 0x000f0000
220 #define ARM_CDSP_MSR_F_SHIFT 16
221 #define ARM_CDSP_MSR_RI_MASK 0x00000f00
222 #define ARM_CDSP_MSR_RI_SHIFT 8
223 #define ARM_CDSP_MSR_IMM_MASK 0x000000ff
224 #define ARM_CDSP_MSR_ISIMM_MASK 0x02000000
225
226 #define ARM_CDSP_BEX_TYPE_MASK 0x000000f0
227 #define ARM_CDSP_BEX_TYPE_SHIFT 4
228 #define ARM_CDSP_BEX_TYPE_X 1
229 #define ARM_CDSP_BEX_TYPE_J 2
230 #define ARM_CDSP_BEX_TYPE_L 3
231
232 #define ARM_CDSP_SAT_OP_MASK 0x00600000
233 #define ARM_CDSP_SAT_OP_SHIFT 21
234
235 #define ARM_CDSP_BKPT_UIMM_MASK 0x000fff00
236 #define ARM_CDSP_BKPT_UIMM_SHIFT 8
237 #define ARM_CDSP_BKPT_LIMM_MASK 0x0000000f
238
239 #define ARM_CDSP_SMUL_OP_MASK 0x00600000
240 #define ARM_CDSP_SMUL_OP_SHIFT 21
241 #define ARM_CDSP_SMUL_X_MASK 0x00000020
242 #define ARM_CDSP_SMUL_Y_MASK 0x00000040
243
244 /*
245 * Interrupt
246 */
247 #define ARM_SWI_IMM_MASK 0x00ffffff
248
249 /*
250 * Branch and Link pieces.
251 */
252 #define ARM_BRANCH_LBIT_MASK 0x01000000
253 #define ARM_BRANCH_IMM_MASK 0x00ffffff
254 #define ARM_BRANCH_SIGN_MASK 0x00800000
255 #define ARM_BRANCH_POS_SIGN 0x00ffffff
256 #define ARM_BRANCH_NEG_SIGN 0xff000000
257 #define ARM_BRANCH_SHIFT 2
258
259 /*
260 * Unconditional instructions
261 */
262 #define ARM_UNI_CPS_MASK 0x0ff10010 /* Change processor state */
263 #define ARM_UNI_CPS_TARG 0x01000000
264 #define ARM_UNI_SE_MASK 0x0fff0078 /* Set endianess */
265 #define ARM_UNI_SE_TARG 0x01010000
266 #define ARM_UNI_PLD_MASK 0x0d70f000 /* Cach preload */
267 #define ARM_UNI_PLD_TARG 0x0550f000
268 #define ARM_UNI_SRS_MASK 0x0e5f0f00 /* Save return state */
269 #define ARM_UNI_SRS_TARG 0x084d0500
270 #define ARM_UNI_RFE_MASK 0x0e500f00 /* Return from exception */
271 #define ARM_UNI_RFE_TARG 0x08100a00
272 #define ARM_UNI_BLX_MASK 0x0e000000 /* Branch with Link / Thumb */
273 #define ARM_UNI_BLX_TARG 0x0a000000
274 #define ARM_UNI_CODRT_MASK 0x0fe00000 /* double reg to coproc */
275 #define ARM_UNI_CODRT_TARG 0x0c400000
276 #define ARM_UNI_CORT_MASK 0x0f000010 /* single reg to coproc */
277 #define ARM_UNI_CORT_TARG 0x0e000010
278 #define ARM_UNI_CODP_MASK 0x0f000010 /* coproc data processing */
279 #define ARM_UNI_CODP_TARG 0x0e000000
280
281 #define ARM_UNI_CPS_IMOD_MASK 0x000c0000
282 #define ARM_UNI_CPS_IMOD_SHIFT 18
283 #define ARM_UNI_CPS_MMOD_MASK 0x00020000
284 #define ARM_UNI_CPS_A_MASK 0x00000100
285 #define ARM_UNI_CPS_I_MASK 0x00000080
286 #define ARM_UNI_CPS_F_MASK 0x00000040
287 #define ARM_UNI_CPS_MODE_MASK 0x0000001f
288
289 #define ARM_UNI_SE_BE_MASK 0x00000200
290
291 #define ARM_UNI_SRS_WBIT_MASK 0x00200000
292 #define ARM_UNI_SRS_MODE_MASK 0x0000000f
293
294 #define ARM_UNI_RFE_WBIT_MASK 0x00200000
295
296 #define ARM_UNI_BLX_IMM_MASK 0x00ffffff
297
298 /*
299 * Definitions of the ARM Media instruction extension space.
300 */
301 #define ARM_MEDIA_L1_MASK 0x01800000 /* First level breakdown */
302 #define ARM_MEDIA_L1_SHIFT 23
303
304 #define ARM_MEDIA_OP1_MASK 0x00700000
305 #define ARM_MEDIA_OP1_SHIFT 20
306 #define ARM_MEDIA_OP2_MASK 0x000000e0
307 #define ARM_MEDIA_OP2_SHIFT 5
308
309 #define ARM_MEDIA_RN_MASK 0x000f0000
310 #define ARM_MEDIA_RN_SHIFT 16
311 #define ARM_MEDIA_RD_MASK 0x0000f000
312 #define ARM_MEDIA_RD_SHIFT 12
313 #define ARM_MEDIA_RS_MASK 0x00000f00
314 #define ARM_MEDIA_RS_SHIFT 8
315 #define ARM_MEDIA_RM_MASK 0x0000000f
316
317 #define ARM_MEDIA_MULT_X_MASK 0x00000020
318
319 #define ARM_MEDIA_HPACK_MASK 0x00700020 /* Halfword pack */
320 #define ARM_MEDIA_HPACK_TARG 0x00000000
321 #define ARM_MEDIA_WSAT_MASK 0x00200020 /* Word saturate */
322 #define ARM_MEDIA_WSAT_TARG 0x00200000
323 #define ARM_MEDIA_PHSAT_MASK 0x003000e0 /* Parallel halfword saturate */
324 #define ARM_MEDIA_PHSAT_TARG 0x00200020
325 #define ARM_MEDIA_REV_MASK 0x007000e0 /* Byte rev. word */
326 #define ARM_MEDIA_REV_TARG 0x00300020
327 #define ARM_MEDIA_BRPH_MASK 0x007000e0 /* Byte rev. packed halfword */
328 #define ARM_MEDIA_BRPH_TARG 0x003000a0
329 #define ARM_MEDIA_BRSH_MASK 0x007000e0 /* Byte rev. signed halfword */
330 #define ARM_MEDIA_BRSH_TARG 0x007000a0
331 #define ARM_MEDIA_SEL_MASK 0x008000e0 /* Select bytes */
332 #define ARM_MEDIA_SEL_TARG 0x000000a0
333 #define ARM_MEDIA_SZE_MASK 0x000000e0 /* Sign/zero extend */
334 #define ARM_MEDIA_SZE_TARG 0x00000030
335
336 #define ARM_MEDIA_HPACK_OP_MASK 0x00000040
337 #define ARM_MEDIA_HPACK_SHIFT_MASK 0x00000f80
338 #define ARM_MEDIA_HPACK_SHIFT_IMM 7
339
340 #define ARM_MEDIA_SAT_U_MASK 0x00400000
341 #define ARM_MEDIA_SAT_IMM_MASK 0x001f0000
342 #define ARM_MEDIA_SAT_IMM_SHIFT 16
343 #define ARM_MEDIA_SAT_SHI_MASK 0x00000f80
344 #define ARM_MEDIA_SAT_SHI_SHIFT 7
345 #define ARM_MEDIA_SAT_STYPE_MASK 0x00000040
346
347 #define ARM_MEDIA_SZE_S_MASK 0x00400000
348 #define ARM_MEDIA_SZE_OP_MASK 0x00300000
349 #define ARM_MEDIA_SZE_OP_SHIFT 20
350 #define ARM_MEDIA_SZE_ROT_MASK 0x00000c00
351 #define ARM_MEDIA_SZE_ROT_SHIFT 10
352
353 /*
354 * Definitions for coprocessor instructions
355 */
356 #define ARM_COPROC_RN_MASK 0x000f0000
357 #define ARM_COPROC_RN_SHIFT 16
358 #define ARM_COPROC_RD_MASK 0x0000f000
359 #define ARM_COPROC_RD_SHIFT 12
360 #define ARM_COPROC_RM_MASK 0x0000000f
361 #define ARM_COPROC_NUM_MASK 0x00000f00
362 #define ARM_COPROC_NUM_SHIFT 8
363
364 #define ARM_COPROC_CDP_OP1_MASK 0x00f00000
365 #define ARM_COPROC_CDP_OP1_SHIFT 20
366 #define ARM_COPROC_CDP_OP2_MASK 0x000000e0
367 #define ARM_COPROC_CDP_OP2_SHIFT 5
368
369 #define ARM_COPROC_CRT_OP1_MASK 0x00e00000
370 #define ARM_COPROC_CRT_OP1_SHIFT 21
371 #define ARM_COPROC_CRT_OP2_MASK 0x000000e0
372 #define ARM_COPROC_CRT_OP2_SHIFT 5
373 #define ARM_COPROC_CRT_DIR_MASK 0x00100000 /* MCR or MRC */
374
375 #define ARM_COPROC_DRT_MASK 0x01e00000
376 #define ARM_COPROC_DRT_TARG 0x00400000
377 #define ARM_COPROC_DRT_OP_MASK 0x000000f0
378 #define ARM_COPROC_DRT_OP_SHIFT 4
379 #define ARM_COPROC_DRT_DIR_MASK 0x00100000 /* MCRR or MRRC */
380
381 #define ARM_COPROC_LS_P_MASK 0x01000000
382 #define ARM_COPROC_LS_U_MASK 0x00800000
383 #define ARM_COPROC_LS_N_MASK 0x00400000
384 #define ARM_COPROC_LS_W_MASK 0x00200000
385 #define ARM_COPROC_LS_L_MASK 0x00100000
386 #define ARM_COPROC_LS_IMM_MASK 0x000000ff
387
388 /*
389 * This is the table of condition codes that instructions might have. Every
390 * instruction starts with a four bit code. The last two codes are special.
391 * 0b1110 is the always condition. Therefore we leave off its mneomic extension
392 * and treat it as the empty string. The condition code 0b1111 takes us to a
393 * separate series of encoded instructions and therefore we go elsewhere with
394 * them.
395 */
396 static const char *arm_cond_names[] = {
397 "eq", /* Equal */
398 "ne", /* Not Equal */
399 "cs/hs", /* Carry set/unsigned higher or same */
400 "cc/lo", /* Carry clear/unsigned lower */
401 "mi", /* Minus/negative */
402 "pl", /* Plus/positive or zero */
403 "vs", /* Overflow */
404 "vc", /* No overflow */
405 "hi", /* Unsigned higher */
406 "ls", /* Unsigned lower or same */
407 "ge", /* Signed greater than or equal */
408 "lt", /* Signed less than */
409 "gt", /* Signed greater than */
410 "le", /* Signed less than or equal */
411 "", /* AL - Always (unconditional) */
412 NULL /* Not a condition code */
413 };
414
415 typedef enum arm_cond_code {
416 ARM_COND_EQ, /* Equal */
417 ARM_COND_NE, /* Not Equal */
418 ARM_COND_CSHS, /* Carry set/unsigned higher or same */
419 ARM_COND_CCLO, /* Carry clear/unsigned lower */
420 ARM_COND_MI, /* Minus/negative */
421 ARM_COND_PL, /* Plus/positive or zero */
422 ARM_COND_VS, /* Overflow */
423 ARM_COND_VC, /* No overflow */
424 ARM_COND_HI, /* Unsigned higher */
425 ARM_COND_LS, /* Unsigned lower or same */
426 ARM_COND_GE, /* Signed greater than or equal */
427 ARM_COND_LT, /* Signed less than */
428 ARM_COND_GT, /* Signed greater than */
429 ARM_COND_LE, /* Signed less than or equal */
430 ARM_COND_AL, /* AL - Always (unconditional) */
431 ARM_COND_NACC /* Not a condition code */
432 } arm_cond_code_t;
433
434 /*
435 * Registers are encoded surprisingly sanely. It's a 4-bit value that indicates
436 * which register in question we're working with.
437 */
438 static const char *arm_reg_names[] = {
439 "r0",
440 "r1",
441 "r2",
442 "r3",
443 "r4",
444 "r5",
445 "r6",
446 "r7",
447 "r8",
448 "fp", /* Alt for r9 */
449 "r10",
450 "r11",
451 "ip", /* Alt for r12 */
452 "sp", /* Alt for r13 */
453 "lr", /* Alt for r14 */
454 "pc" /* Alt for r15 */
455 };
456
457 typedef enum arm_reg {
458 ARM_REG_R0,
459 ARM_REG_R1,
460 ARM_REG_R2,
461 ARM_REG_R3,
462 ARM_REG_R4,
463 ARM_REG_R5,
464 ARM_REG_R6,
465 ARM_REG_R7,
466 ARM_REG_R8,
467 ARM_REG_R9,
468 ARM_REG_R10,
469 ARM_REG_R11,
470 ARM_REG_R12,
471 ARM_REG_R13,
472 ARM_REG_R14,
473 ARM_REG_R15
474 } arm_reg_t;
475
476 /*
477 * Default coprocessor names
478 */
479 static const char *arm_coproc_names[] = {
480 "p0",
481 "p1",
482 "p2",
483 "p3",
484 "p4",
485 "p5",
486 "p6",
487 "p7",
488 "p8",
489 "p9",
490 "p10",
491 "p11",
492 "p12",
493 "p13",
494 "p14",
495 "p15"
496 };
497
498 /*
499 * These are the opcodes for the instructions which are considered data
500 * processing instructions.
501 */
502 static const char *arm_dpi_opnames[] = {
503 "and", /* Logical AND */
504 "eor", /* Logical Exclusive OR */
505 "sub", /* Subtract */
506 "rsb", /* Reverse Subtract */
507 "add", /* Add */
508 "adc", /* Add with Carry */
509 "sbc", /* Subtract with Carry */
510 "rsc", /* Reverse Subtract with Carry */
511 "tst", /* Test */
512 "teq", /* Test Equivalence */
513 "cmp", /* Compare */
514 "cmn", /* Compare negated */
515 "orr", /* Logical (inclusive) OR */
516 "mov", /* Move */
517 "bic", /* Bit clear */
518 "mvn" /* Move not */
519 };
520
521 typedef enum arm_dpi_opcode {
522 DPI_OP_AND, /* Logical AND */
523 DPI_OP_EOR, /* Logical Exclusive OR */
524 DPI_OP_SUB, /* Subtract */
525 DPI_OP_RSB, /* Reverse Subtract */
526 DPI_OP_ADD, /* Add */
527 DPI_OP_ADC, /* Add with Carry */
528 DPI_OP_SBC, /* Subtract with Carry */
529 DPI_OP_RSC, /* Reverse Subtract with Carry */
530 DPI_OP_TST, /* Test */
531 DPI_OP_TEQ, /* Test Equivalence */
532 DPI_OP_CMP, /* Compare */
533 DPI_OP_CMN, /* Compare negated */
534 DPI_OP_ORR, /* Logical (inclusive) OR */
535 DPI_OP_MOV, /* Move */
536 DPI_OP_BIC, /* Bit clear */
537 DPI_OP_MVN /* Move not */
538 } arm_dpi_opcode_t;
539
540 const char *arm_dpi_shifts[] = {
541 "lsl", /* Logical shift left */
542 "lsr", /* Logical shift right */
543 "asr", /* Arithmetic shift right */
544 "ror", /* Rotate right */
545 "rrx" /* Rotate right with extend. This is a special case of ror */
546 };
547
548 typedef enum arm_dpi_shift_code {
549 DPI_S_LSL, /* Logical shift left */
550 DPI_S_LSR, /* Logical shift right */
551 DPI_S_ASR, /* Arithmetic shift right */
552 DPI_S_ROR, /* Rotate right */
553 DPI_S_RRX, /* Rotate right with extend. Special case of ror */
554 DPI_S_NONE /* No shift code */
555 } arm_dpi_shift_code_t;
556
557 #define ARM_DPI_SHIFTER_IMM32 0x00
558 #define ARM_DPI_SHIFTER_SIMM 0x01
559 #define ARM_DPI_SHIFTER_SREG 0x02
560
561 typedef struct arm_dpi_shifter_imm {
562 uint8_t dpisi_rot; /* Rotation amount */
563 uint8_t dpisi_imm; /* Immediate value */
564 } arm_dpi_shifter_imm_t;
565
566 typedef struct arm_dpi_shifter_simm {
567 uint8_t dpiss_imm; /* Shift value */
568 arm_dpi_shift_code_t dpiss_code; /* Shift type */
569 arm_reg_t dpiss_targ; /* Target register */
570 } arm_dpi_shifter_simm_t;
571
572 typedef struct arm_dpi_shifter_sreg {
573 arm_reg_t dpisr_val; /* reg with shift value */
574 arm_dpi_shift_code_t dpisr_code; /* Shift type */
575 arm_reg_t dpisr_targ; /* Target register */
576 } arm_dpi_shifter_sreg_t;
577
578 typedef struct arm_dpi_inst {
579 arm_dpi_opcode_t dpii_op; /* dpi opcode */
580 arm_cond_code_t dpii_cond; /* condition code */
581 int dpii_sbit; /* value of S bit */
582 arm_reg_t dpii_rn; /* first operand */
583 arm_reg_t dpii_rd; /* destination operand */
584 int dpii_stype; /* type of shifter */
585 union { /* shifter values */
586 arm_dpi_shifter_imm_t dpii_im;
587 arm_dpi_shifter_simm_t dpii_si;
588 arm_dpi_shifter_sreg_t dpii_ri;
589 } dpii_un;
590 } arm_dpi_inst_t;
591
592 /*
593 * This table contains the names of the load store multiple addressing modes.
594 * The P and U bits are supposed to be combined to index into this. You should
595 * do this by doing P << 1 | U.
596 */
597 static const char *arm_lsm_mode_names[] = {
598 "da",
599 "ia",
600 "db",
601 "ib"
602 };
603
604 /*
605 * The MSR field has a four bit field mask. Each bit correspons to a letter.
606 * From high to low, f, s, x, c. At least one must be specified, hence 0 is
607 * NULL. The preferred manual ordering of these is csxf.
608 */
609 static const char *arm_cdsp_msr_field_names[] = {
610 NULL,
611 "c", /* 0001 */
612 "x", /* 0010 */
613 "cx", /* 0011 */
614 "s", /* 0100 */
615 "cs", /* 0101 */
616 "sx", /* 0110 */
617 "csx", /* 0111 */
618 "f", /* 1000 */
619 "cf", /* 1001 */
620 "xf", /* 1010 */
621 "cxf", /* 1011 */
622 "sf", /* 1100 */
623 "csf", /* 1101 */
624 "sxf", /* 1110 */
625 "csxf" /* 1111 */
626 };
627
628 /*
629 * Names for specific saturating add and subtraction instructions from the
630 * extended control and dsp instructino section.
631 */
632 static const char *arm_cdsp_sat_opnames[] = {
633 "add",
634 "sub",
635 "dadd",
636 "dsub"
637 };
638
639 static const char *arm_padd_p_names[] = {
640 NULL, /* 000 */
641 "s", /* 001 */
642 "q", /* 010 */
643 "sh", /* 011 */
644 NULL, /* 100 */
645 "u", /* 101 */
646 "uq", /* 110 */
647 "uh", /* 111 */
648 };
649
650 static const char *arm_padd_i_names[] = {
651 "add16", /* 000 */
652 "addsubx", /* 001 */
653 "subaddx", /* 010 */
654 "sub16", /* 011 */
655 "add8", /* 100 */
656 NULL, /* 101 */
657 NULL, /* 110 */
658 "sub8", /* 111 */
659 };
660
661 static const char *arm_extend_rot_names[] = {
662 "", /* 0b00, ROR #0 */
663 ", ror #8", /* 0b01 */
664 ", ror #16", /* 0b10 */
665 ", ror #24" /* 0b11 */
666 };
667
668 /*
669 * There are sixteen data processing instructions (dpi). They come in a few
670 * different forms which are based on whether immediate values are used and
671 * whether or not some special purpose shifting is done. We use this one entry
672 * point to cover all the different types.
673 *
674 * From the ARM arch manual:
675 *
676 * <opcode1>{<cond>}{S} <Rd>,<shifter>
677 * <opcode1> := MOV | MVN
678 * <opcode2>{<cond>} <Rn>,<shifter>
679 * <opcode2> := CMP, CMN, TST, TEQ
680 * <opcode3>{<cond>{S} <Rd>,<Rn>, <shifter>
681 * <opcode3> := ADD | SUB | RSB | ADC | SBC | RSC | AND | BIC | EOR | ORR
682 *
683 * 31 - 28|27 26 |25 | 24-21 |20 | 19-16 | 15-12 | 11 - 0
684 * [ cond | 0 0 | I | opcode | S | Rn | Rd | shifter ]
685 *
686 * I bit: Determines whether shifter_operand is immediate or register based
687 * S bit: Determines whether or not the insn updates condition codes
688 * Rn: First source operand register
689 * Rd: Destination register
690 * shifter: Specifies the second operand
691 *
692 * There are three primary encodings:
693 *
694 * 32-bit immediate
695 * 31 - 28|27 26|25 |24-21 |20|19-16| 15-12|11 - 8 |7 - 0
696 * [ cond | 0 0| 1 |opcode| S|Rn | Rd |rotate_imm|immed_8 ]
697 *
698 * Immediate shifts
699 * 31 - 28|27 26|25 |24-21 |20|19-16|15-12|11 - 7 |6 5 |4|3-0
700 * [ cond | 0 0| 0 |opcode| S|Rn |Rd |shift_imm|shift|0|Rm ]
701 *
702 * Register shifts
703 * 31 - 28|27 26|25 |24-21 |20|19-16|15-12|11 - 8|7|6 5 |4|3-0
704 * [ cond | 0 0| 0 |opcode| S|Rn |Rd |Rs |0|shift|1|Rm ]
705 *
706 * There are four different kinds of shifts that work with both immediate and
707 * register shifts:
708 * o Logical shift left 0b00 (LSL)
709 * o Logical shift right 0b01 (LSR)
710 * o Arithmetic shift right 0b10 (ASR)
711 * o Rotate right 0b11 (ROR)
712 * There is one special shift which only works with immediate shift format:
713 * o If shift_imm = 0 and shift = 0b11, then it is a rotate right with extend
714 * (RRX)
715 *
716 * Finally there is one special indication for no shift. An immediate shift
717 * whose shift_imm = shift = 0. This is a shortcut to a direct value from the
718 * register.
719 *
720 * While processing this, we first build up all the information into the
721 * arm_dpi_inst_t and then from there we go and print out the format based on
722 * the opcode and shifter. As per the rough grammar above we have to print
723 * different sets of instructions in different ways.
724 */
725 static int
726 arm_dis_dpi(uint32_t in, arm_cond_code_t cond, char *buf, size_t buflen)
727 {
728 arm_dpi_inst_t dpi_inst;
729 int ibit, bit4;
730 size_t len;
731
732 dpi_inst.dpii_op = (in & ARM_DPI_OPCODE_MASK) >> ARM_DPI_OPCODE_SHIFT;
733 dpi_inst.dpii_cond = cond;
734 dpi_inst.dpii_rn = (in & ARM_DPI_RN_MASK) >> ARM_DPI_RN_SHIFT;
735 dpi_inst.dpii_rd = (in & ARM_DPI_RD_MASK) >> ARM_DPI_RD_SHIFT;
736 dpi_inst.dpii_sbit = in & ARM_DPI_SBIT_MASK;
737
738 ibit = in & ARM_DPI_IBIT_MASK;
739 bit4 = in & ARM_DPI_BIT4_MASK;
740
741 if (ibit) {
742 /* 32-bit immediate */
743 dpi_inst.dpii_stype = ARM_DPI_SHIFTER_IMM32;
744 dpi_inst.dpii_un.dpii_im.dpisi_rot = (in &
745 ARM_DPI_IMM_ROT_MASK) >> ARM_DPI_IMM_ROT_SHIFT;
746 dpi_inst.dpii_un.dpii_im.dpisi_imm = in & ARM_DPI_IMM_VAL_MASK;
747 } else if (bit4) {
748 /* Register shift */
749 dpi_inst.dpii_stype = ARM_DPI_SHIFTER_SREG;
750 dpi_inst.dpii_un.dpii_ri.dpisr_val = (in &
751 ARM_DPI_REGS_RS_MASK) >> ARM_DPI_REGS_RS_SHIFT;
752 dpi_inst.dpii_un.dpii_ri.dpisr_targ = in &
753 ARM_DPI_REGS_RM_MASK;
754 dpi_inst.dpii_un.dpii_ri.dpisr_code = in &
755 ARM_DPI_REGS_SHIFT_MASK >> ARM_DPI_REGS_SHIFT_SHIFT;
756 } else {
757 /* Immediate shift */
758 dpi_inst.dpii_stype = ARM_DPI_SHIFTER_SIMM;
759 dpi_inst.dpii_un.dpii_si.dpiss_imm = (in &
760 ARM_DPI_IMS_SHIMM_MASK) >> ARM_DPI_IMS_SHIMM_SHIFT;
761 dpi_inst.dpii_un.dpii_si.dpiss_code = (in &
762 ARM_DPI_IMS_SHIFT_MASK) >> ARM_DPI_IMS_SHIFT_SHIFT;
763 dpi_inst.dpii_un.dpii_si.dpiss_targ = in & ARM_DPI_IMS_RM_MASK;
764 if (dpi_inst.dpii_un.dpii_si.dpiss_code == DPI_S_ROR &&
765 dpi_inst.dpii_un.dpii_si.dpiss_imm == 0)
766 dpi_inst.dpii_un.dpii_si.dpiss_code = DPI_S_RRX;
767
768 if (dpi_inst.dpii_un.dpii_si.dpiss_code == DPI_S_LSL &&
769 dpi_inst.dpii_un.dpii_si.dpiss_imm == 0)
770 dpi_inst.dpii_un.dpii_si.dpiss_code = DPI_S_NONE;
771 }
772
773 /*
774 * Print everything before the shifter based on the instruction
775 */
776 switch (dpi_inst.dpii_op) {
777 case DPI_OP_MOV:
778 case DPI_OP_MVN:
779 len = snprintf(buf, buflen, "%s%s%s %s",
780 arm_dpi_opnames[dpi_inst.dpii_op],
781 arm_cond_names[dpi_inst.dpii_cond],
782 dpi_inst.dpii_sbit != 0 ? "s" : "",
783 arm_reg_names[dpi_inst.dpii_rd]);
784 break;
785 case DPI_OP_CMP:
786 case DPI_OP_CMN:
787 case DPI_OP_TST:
788 case DPI_OP_TEQ:
789 len = snprintf(buf, buflen, "%s%s %s",
790 arm_dpi_opnames[dpi_inst.dpii_op],
791 arm_cond_names[dpi_inst.dpii_cond],
792 arm_reg_names[dpi_inst.dpii_rn]);
793 break;
794 default:
795 len = snprintf(buf, buflen,
796 "%s%s%s %s, %s", arm_dpi_opnames[dpi_inst.dpii_op],
797 arm_cond_names[dpi_inst.dpii_cond],
798 dpi_inst.dpii_sbit != 0 ? "s" : "",
799 arm_reg_names[dpi_inst.dpii_rd],
800 arm_reg_names[dpi_inst.dpii_rn]);
801 break;
802 }
803
804 if (len >= buflen)
805 return (-1);
806 buflen -= len;
807 buf += len;
808
809 /*
810 * Print the shifter as appropriate
811 */
812 switch (dpi_inst.dpii_stype) {
813 case ARM_DPI_SHIFTER_IMM32: {
814 uint32_t rawimm, imm;
815 int rawrot, rot;
816
817 rawimm = dpi_inst.dpii_un.dpii_im.dpisi_imm;
818 rawrot = dpi_inst.dpii_un.dpii_im.dpisi_rot;
819
820 rot = rawrot * 2;
821 imm = (rawimm << (32 - rot)) | (rawimm >> rot);
822
823 len = snprintf(buf, buflen, ", #%u, %d ; 0x%08x", rawimm,
824 rawrot, imm);
825 break;
826 }
827 case ARM_DPI_SHIFTER_SIMM:
828 if (dpi_inst.dpii_un.dpii_si.dpiss_code == DPI_S_NONE) {
829 len = snprintf(buf, buflen, ", %s",
830 arm_reg_names[dpi_inst.dpii_un.dpii_si.dpiss_targ]);
831 break;
832 }
833 if (dpi_inst.dpii_un.dpii_si.dpiss_code == DPI_S_RRX) {
834 len = snprintf(buf, buflen, ", %s rrx",
835 arm_reg_names[dpi_inst.dpii_un.dpii_si.dpiss_targ]);
836 break;
837 }
838 len = snprintf(buf, buflen, ", %s, %s #%d",
839 arm_reg_names[dpi_inst.dpii_un.dpii_si.dpiss_targ],
840 arm_dpi_shifts[dpi_inst.dpii_un.dpii_si.dpiss_code],
841 dpi_inst.dpii_un.dpii_si.dpiss_imm);
842 break;
843 case ARM_DPI_SHIFTER_SREG:
844 len = snprintf(buf, buflen, ", %s, %s %s",
845 arm_reg_names[dpi_inst.dpii_un.dpii_ri.dpisr_targ],
846 arm_dpi_shifts[dpi_inst.dpii_un.dpii_ri.dpisr_code],
847 arm_reg_names[dpi_inst.dpii_un.dpii_ri.dpisr_val]);
848 break;
849 }
850
851 return (len < buflen ? 0 : -1);
852 }
853
854 /*
855 * This handles the byte and word size loads and stores. It does not handle the
856 * multi-register loads or the 'extra' ones. The instruction has the generic
857 * form off:
858 *
859 * 31 - 28|27 26 |25|24|23|22|21|20|19-16|15-12|11 - 0
860 * [ cond | 0 0 |I |P |U |B |W |L | Rn | Rd |mode_specific]
861 *
862 * Here the bits mean the following:
863 *
864 * Rn: The base register used by the addressing mode
865 * Rd: The register to load to or store from
866 * L bit: If L==1 then a load, else store
867 * B bit: If B==1 then work on a byte, else a 32-bit word
868 *
869 * The remaining pieces determine the mode we are operating in:
870 * I bit: If 0 use immediate offsets, otherwise if 1 used register based offsets
871 * P bit: If 0 use post-indexed addressing. If 1, indexing mode is either offset
872 * addessing or pre-indexed addressing based on the W bit.
873 * U bit: If 1, offset is added to base, if 0 offset is subtracted from base
874 * W bit: This bits interpretation varies based on the P bit. If P is zero then
875 * W indicates whether a normal memory access is performed or if a read
876 * from user memory is performed (W = 1).
877 * If P is 1 then then when W = 0 the base register is not updated and
878 * when W = 1 the calculated address is written back to the base
879 * register.
880 *
881 * Based on these combinations there are a total of nine different operating
882 * modes, though not every LDR and STR variant can reach them all.
883 */
884 static int
885 arm_dis_ldstr(uint32_t in, char *buf, size_t buflen)
886 {
887 arm_cond_code_t cc;
888 arm_reg_t rd, rn, rm;
889 int ibit, pbit, ubit, bbit, wbit, lbit;
890 arm_dpi_shift_code_t sc;
891 uint8_t simm;
892 size_t len;
893
894 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
895 ibit = in & ARM_LS_IBIT_MASK;
896 pbit = in & ARM_LS_PBIT_MASK;
897 ubit = in & ARM_LS_UBIT_MASK;
898 bbit = in & ARM_LS_BBIT_MASK;
899 wbit = in & ARM_LS_WBIT_MASK;
900 lbit = in & ARM_LS_LBIT_MASK;
901 rd = (in & ARM_LS_RD_MASK) >> ARM_LS_RD_SHIFT;
902 rn = (in & ARM_LS_RN_MASK) >> ARM_LS_RN_SHIFT;
903
904 len = snprintf(buf, buflen, "%s%s%s%s %s, ", lbit != 0 ? "ldr" : "str",
905 arm_cond_names[cc], bbit != 0 ? "b" : "",
906 (pbit == 0 && wbit != 0) ? "t" : "",
907 arm_reg_names[rd]);
908 if (len >= buflen)
909 return (-1);
910
911 /* Figure out the specifics of the encoding for the rest */
912 if (ibit == 0 && pbit != 0) {
913 /*
914 * This is the immediate offset mode (A5.2.2). That means that
915 * we have something of the form [ <Rn>, #+/-<offset_12> ]. All
916 * of the mode specific bits contribute to offset_12. We also
917 * handle the pre-indexed version (A5.2.5) which depends on the
918 * wbit being set.
919 */
920 len += snprintf(buf + len, buflen - len, "[%s, #%s%d]%s",
921 arm_reg_names[rn], ubit != 0 ? "" : "-",
922 in & ARM_LS_IMM_MASK, wbit != 0 ? "!" : "");
923 } else if (ibit != 0 && pbit != 0) {
924 /*
925 * This handles A5.2.2, A5.2.3, A5.2.6, and A5.2.7. We can have
926 * one of two options. If the non-rm bits (11-4) are all zeros
927 * then we have a special case of a register offset is just
928 * being added. Otherwise we have a scaled register offset where
929 * the shift code matters.
930 */
931 rm = in & ARM_LS_REG_RM_MASK;
932 len += snprintf(buf + len, buflen - len, "[%s, %s%s",
933 arm_reg_names[rn], ubit != 0 ? "" : "-",
934 arm_reg_names[rm]);
935 if (len >= buflen)
936 return (-1);
937 if ((in & ARM_LS_REG_NRM_MASK) != 0) {
938 simm = (in & ARM_LS_SCR_SIMM_MASK) >>
939 ARM_LS_SCR_SIMM_SHIFT;
940 sc = (in & ARM_LS_SCR_SCODE_MASK) >>
941 ARM_LS_SCR_SCODE_SHIFT;
942
943 if (simm == 0 && sc == DPI_S_ROR)
944 sc = DPI_S_RRX;
945
946 len += snprintf(buf + len, buflen - len, "%s",
947 arm_dpi_shifts[sc]);
948 if (len >= buflen)
949 return (-1);
950 if (sc != DPI_S_RRX) {
951 len += snprintf(buf + len, buflen - len, " #%d",
952 simm);
953 if (len >= buflen)
954 return (-1);
955 }
956 }
957 len += snprintf(buf + len, buflen - len, "]%s",
958 wbit != 0 ? "!" : "");
959 } else if (ibit == 0 && pbit == 0 && wbit == 0) {
960 /* A5.2.8 immediate post-indexed */
961 len += snprintf(buf + len, buflen - len, "[%s], #%s%d",
962 arm_reg_names[rn], ubit != 0 ? "" : "-",
963 in & ARM_LS_IMM_MASK);
964 } else if (ibit != 0 && pbit == 0 && wbit == 0) {
965 /* A5.2.9 and A5.2.10 */
966 rm = in & ARM_LS_REG_RM_MASK;
967 len += snprintf(buf + len, buflen - len, "[%s], %s%s",
968 arm_reg_names[rn], ubit != 0 ? "" : "-",
969 arm_reg_names[rm]);
970 if ((in & ARM_LS_REG_NRM_MASK) != 0) {
971 simm = (in & ARM_LS_SCR_SIMM_MASK) >>
972 ARM_LS_SCR_SIMM_SHIFT;
973 sc = (in & ARM_LS_SCR_SCODE_MASK) >>
974 ARM_LS_SCR_SCODE_SHIFT;
975
976 if (simm == 0 && sc == DPI_S_ROR)
977 sc = DPI_S_RRX;
978
979 len += snprintf(buf + len, buflen - len, "%s",
980 arm_dpi_shifts[sc]);
981 if (len >= buflen)
982 return (-1);
983 if (sc != DPI_S_RRX)
984 len += snprintf(buf + len, buflen - len,
985 " #%d", simm);
986 }
987 }
988
989 return (len < buflen ? 0 : -1);
990 }
991
992 static void
993 print_range(char **bufp, size_t *buflenp, uint16_t regs, uint16_t precede)
994 {
995 char *buf = *bufp;
996 size_t buflen = *buflenp;
997 boolean_t cont = B_FALSE;
998 int minreg = -1;
999 int i;
1000
1001 *buf = '\0';
1002
1003 if (precede && regs)
1004 strlcat(buf, ", ", buflen);
1005
1006 for (i = 0; i < 16; i++) {
1007 boolean_t present = (regs & (1 << i)) != 0;
1008 boolean_t lastreg = (regs & (2 << i)) == 0;
1009
1010 if (!present)
1011 continue;
1012
1013 if (minreg == -1) {
1014 if (cont)
1015 strlcat(buf, ", ", buflen);
1016
1017 strlcat(buf, arm_reg_names[i], buflen);
1018
1019 if (!lastreg)
1020 minreg = i;
1021 } else {
1022 if (lastreg) {
1023 strlcat(buf, "-", buflen);
1024 strlcat(buf, arm_reg_names[i], buflen);
1025 minreg = -1;
1026 }
1027 }
1028
1029 cont = B_TRUE;
1030 }
1031
1032 *bufp += strlen(buf);
1033 *buflenp -= strlen(buf);
1034 }
1035
1036 static size_t
1037 print_reg_list(char *buf, size_t buflen, uint16_t regs)
1038 {
1039 char *save = buf;
1040
1041 print_range(&buf, &buflen, regs & 0x01ff, 0);
1042 print_range(&buf, &buflen, regs & 0x0200, regs & 0x01ff); /* fp */
1043 print_range(&buf, &buflen, regs & 0x0c00, regs & 0x03ff);
1044 print_range(&buf, &buflen, regs & 0x1000, regs & 0x0fff); /* ip */
1045 print_range(&buf, &buflen, regs & 0x2000, regs & 0x1fff); /* sp */
1046 print_range(&buf, &buflen, regs & 0x4000, regs & 0x3fff); /* lr */
1047 print_range(&buf, &buflen, regs & 0x8000, regs & 0x7fff); /* pc */
1048
1049 return (strlen(save));
1050 }
1051
1052 /*
1053 * This handles load and store multiple instructions. The general format is as
1054 * follows:
1055 *
1056 * 31 - 28|27 26 25|24|23|22|21|20|19-16|15-0
1057 * [ cond | 1 0 0 |P |U |S |W |L | Rn | register set
1058 *
1059 * The register set has one bit per register. If a bit is set it indicates that
1060 * register and if it is not set then it indicates that the register is not
1061 * included in this.
1062 *
1063 * S bit: If the instruction is a LDM and we load the PC, the S == 1 tells us to
1064 * load the CPSR from SPSR after the other regs are loaded. If the instruction
1065 * is a STM or LDM without touching the PC it indicates that if we are
1066 * privileged we should send the banked registers.
1067 *
1068 * L bit: Where this is a load or store. Load is active high.
1069 *
1070 * P bit: If P == 0 then Rn is included in the memory region transfers and its
1071 * location is dependent on the U bit. It is at the top (U == 0) or bottom (U ==
1072 * 1). If P == 1 then it is excluded and lies one word beyond the top (U == 0)
1073 * or bottom based on the U bit.
1074 *
1075 * U bit: If U == 1 then the transfer is made upwards and if U == 0 then the
1076 * transfer is made downwards.
1077 *
1078 * W bit: If set then we incremet the base register after the transfer. It is
1079 * modified by 4 times the number of registers in the list. If the U bit is
1080 * positive then that value is added to Rn otherwise it is subtracted.
1081 *
1082 * The overal layout for this is
1083 * (LDM|STM){<cond>}<addressing mode> Rn{!}, <registers>{^}. Here the ! is based
1084 * on having the W bit set. The ^ bit depends on whether S is set or not.
1085 *
1086 * There are four normal addressing modes: IA, IB, DA, DB. There are also
1087 * corresponding stack addressing modes that exist. However we have no way of
1088 * knowing which are the ones being used, therefore we are going to default to
1089 * the non-stack versions which are listed as the primary.
1090 *
1091 * Finally the last useful bit is how the registers list is specified. It is a
1092 * comma separated list inside of { }. However, a user may separate a contiguous
1093 * range by the use of a -, eg. R0 - R4. However, it is impossible for us to map
1094 * back directly to what the user did. So for now, we punt on second down and
1095 * instead just list each indidvidual register rather than attempt a joining
1096 * routine.
1097 */
1098 static int
1099 arm_dis_ldstr_multi(uint32_t in, char *buf, size_t buflen)
1100 {
1101 int sbit, wbit, lbit;
1102 uint16_t regs, addr_mode;
1103 arm_reg_t rn;
1104 arm_cond_code_t cc;
1105 size_t len;
1106
1107 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
1108 sbit = in & ARM_LSM_SBIT_MASK;
1109 wbit = in & ARM_LSM_WBIT_MASK;
1110 lbit = in & ARM_LSM_LBIT_MASK;
1111 rn = (in & ARM_LSM_RN_MASK) >> ARM_LSM_RN_SHIFT;
1112 regs = in & ARM_LSM_RLIST_MASK;
1113 addr_mode = (in & ARM_LSM_ADDR_MASK) >> ARM_LSM_ADDR_SHIFT;
1114
1115 if ((lbit == 0 && addr_mode == 2 && rn == ARM_REG_R13 && wbit != 0) ||
1116 (lbit != 0 && addr_mode == 1 && rn == ARM_REG_R13 && wbit != 0))
1117 len = snprintf(buf, buflen, "%s%s { ",
1118 lbit != 0 ? "pop" : "push",
1119 arm_cond_names[cc]);
1120 else
1121 len = snprintf(buf, buflen, "%s%s%s %s%s, { ",
1122 lbit != 0 ? "ldm" : "stm",
1123 arm_cond_names[cc],
1124 arm_lsm_mode_names[addr_mode],
1125 arm_reg_names[rn],
1126 wbit != 0 ? "!" : "");
1127
1128 len += print_reg_list(buf + len, buflen - len, regs);
1129
1130 len += snprintf(buf + len, buflen - len, " }%s", sbit != 0 ? "^" : "");
1131 return (len >= buflen ? -1 : 0);
1132 }
1133
1134 /*
1135 * Here we need to handle miscellaneous loads and stores. This is used to load
1136 * and store signed and unsigned half words. To load a signed byte. And to load
1137 * and store double words. There is no specific store routines for signed bytes
1138 * and halfwords as they are supposed to use the SRB and STRH. There are two
1139 * primary encodings this time. The general case looks like:
1140 *
1141 * 31 - 28|27 - 25|24|23|22|21|20|19-16|15-12|11-8 |7|6|5|4|3-0
1142 * [ cond | 0 |P |U |I |W |L | Rn | Rd |amode|1|S|H|1|amode ]
1143 *
1144 * The I, P, U, and W bits specify the addressing mode.
1145 * The L, S, and H bits describe the type and size.
1146 * Rn: The base register used by the addressing mode
1147 * Rd: The register to load to or store from
1148 *
1149 * The other bits specifically mean:
1150 * I bit: If set to one the address specific pieces are immediate. Otherwise
1151 * they aren't.
1152 * P bit: If P is 0 used post-indexed addressing. If P is 1 its behavior is
1153 * based on the value of W.
1154 * U bit: If U is one the offset is added to the base otherwise subtracted
1155 * W bit: When P is one a value of W == 1 says that the resulting memory address
1156 * should be written back to the base register. The base register isn't touched
1157 * when W is zero.
1158 *
1159 * The L, S, and H bits combine in the following table:
1160 *
1161 * L | S | H | Meaning
1162 * -------------------
1163 * 0 | 0 | 1 | store halfword
1164 * 0 | 1 | 0 | load doubleword
1165 * 0 | 1 | 1 | store doubleword
1166 * 1 | 0 | 1 | load unsigned half word
1167 * 1 | 1 | 0 | load signed byte
1168 * 1 | 1 | 1 | load signed halfword
1169 *
1170 * The final format of this is:
1171 * LDR|STR{<cond>}H|SH|SB|D <rd>, address_mode
1172 */
1173 static int
1174 arm_dis_els(uint32_t in, char *buf, size_t buflen)
1175 {
1176 arm_cond_code_t cc;
1177 arm_reg_t rn, rd;
1178 const char *iname, *suffix;
1179 int lbit, sbit, hbit, pbit, ubit, ibit, wbit;
1180 uint8_t imm;
1181 size_t len;
1182
1183 lbit = in & ARM_ELS_LBIT_MASK;
1184 sbit = in & ARM_ELS_SBIT_MASK;
1185 hbit = in & ARM_ELS_SBIT_MASK;
1186
1187 if (lbit || (sbit && hbit == 0))
1188 iname = "ldr";
1189 else
1190 iname = "str";
1191
1192 if (sbit == 0 && hbit)
1193 suffix = "h";
1194 else if (lbit == 0)
1195 suffix = "d";
1196 else if (sbit && hbit == 0)
1197 suffix = "sb";
1198 else if (sbit && hbit)
1199 suffix = "sh";
1200
1201 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
1202 rn = (in & ARM_ELS_RN_MASK) >> ARM_ELS_RN_SHIFT;
1203 rd = (in & ARM_ELS_RD_MASK) >> ARM_ELS_RD_SHIFT;
1204
1205 len = snprintf(buf, buflen, "%s%s%s %s, ", iname, arm_cond_names[cc],
1206 suffix, arm_reg_names[rd]);
1207 if (len >= buflen)
1208 return (-1);
1209
1210 pbit = in & ARM_ELS_PBIT_MASK;
1211 ubit = in & ARM_ELS_UBIT_MASK;
1212 ibit = in & ARM_ELS_IBIT_MASK;
1213 wbit = in & ARM_ELS_WBIT_MASK;
1214
1215 if (pbit && ibit) {
1216 /* Handle A5.3.2 and A5.3.4 immediate offset and pre-indexed */
1217 /* Bits 11-8 form the upper 4 bits of imm */
1218 imm = (in & ARM_ELS_UP_AM_MASK) >> (ARM_ELS_UP_AM_SHIFT - 4);
1219 imm |= in & ARM_ELS_LOW_AM_MASK;
1220 len += snprintf(buf + len, buflen - len, "[%s, #%s%d]%s",
1221 arm_reg_names[rn],
1222 ubit != 0 ? "" : "-", imm,
1223 wbit != 0 ? "!" : "");
1224 } else if (pbit && ibit == 0) {
1225 /* Handle A5.3.3 and A5.3.5 register offset and pre-indexed */
1226 len += snprintf(buf + len, buflen - len, "[%s %s%s]%s",
1227 arm_reg_names[rn],
1228 ubit != 0 ? "" : "-",
1229 arm_reg_names[in & ARM_ELS_LOW_AM_MASK],
1230 wbit != 0 ? "!" : "");
1231 } else if (pbit == 0 && ibit) {
1232 /* A5.3.6 Immediate post-indexed */
1233 /* Bits 11-8 form the upper 4 bits of imm */
1234 imm = (in & ARM_ELS_UP_AM_MASK) >> (ARM_ELS_UP_AM_SHIFT - 4);
1235 imm |= in & ARM_ELS_LOW_AM_MASK;
1236 len += snprintf(buf + len, buflen - len, "[%s], #%s%d",
1237 arm_reg_names[rn], ubit != 0 ? "" : "-", imm);
1238 } else if (pbit == 0 && ibit == 0) {
1239 /* Handle A 5.3.7 Register post-indexed */
1240 len += snprintf(buf + len, buflen - len, "[%s], %s%s",
1241 arm_reg_names[rn], ubit != 0 ? "" : "-",
1242 arm_reg_names[in & ARM_ELS_LOW_AM_MASK]);
1243 }
1244
1245 return (len >= buflen ? -1 : 0);
1246 }
1247
1248 /*
1249 * Handle SWP and SWPB out of the extra loads/stores extensions.
1250 */
1251 static int
1252 arm_dis_swap(uint32_t in, char *buf, size_t buflen)
1253 {
1254 arm_cond_code_t cc;
1255 arm_reg_t rn, rd, rm;
1256
1257 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
1258 rn = (in & ARM_ELS_RN_MASK) >> ARM_ELS_RN_SHIFT;
1259 rd = (in & ARM_ELS_RD_MASK) >> ARM_ELS_RD_SHIFT;
1260 rm = in & ARM_ELS_RN_MASK;
1261
1262 if (snprintf(buf, buflen, "swp%s%s %s, %s, [%s]",
1263 arm_cond_names[cc],
1264 (in & ARM_ELS_SWAP_BYTE_MASK) ? "b" : "",
1265 arm_reg_names[rd], arm_reg_names[rm], arm_reg_names[rn]) >=
1266 buflen)
1267 return (-1);
1268
1269 return (0);
1270 }
1271
1272 /*
1273 * Handle LDREX and STREX out of the extra loads/stores extensions.
1274 */
1275 static int
1276 arm_dis_lsexcl(uint32_t in, char *buf, size_t buflen)
1277 {
1278 arm_cond_code_t cc;
1279 arm_reg_t rn, rd, rm;
1280 int lbit;
1281 size_t len;
1282
1283 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
1284 rn = (in & ARM_ELS_RN_MASK) >> ARM_ELS_RN_SHIFT;
1285 rd = (in & ARM_ELS_RD_MASK) >> ARM_ELS_RD_SHIFT;
1286 rm = in & ARM_ELS_RN_MASK;
1287 lbit = in & ARM_ELS_LBIT_MASK;
1288
1289 len = snprintf(buf, buflen, "%s%sex %s, ",
1290 lbit != 0 ? "ldr" : "str",
1291 arm_cond_names[cc], arm_reg_names[rd]);
1292 if (len >= buflen)
1293 return (-1);
1294
1295 if (lbit)
1296 len += snprintf(buf + len, buflen - len, "[%s]",
1297 arm_reg_names[rn]);
1298 else
1299 len += snprintf(buf + len, buflen - len, "%s, [%s]",
1300 arm_reg_names[rm], arm_reg_names[rn]);
1301 return (len >= buflen ? -1 : 0);
1302 }
1303
1304 /*
1305 * This is designed to handle the multiplication instruction extension space.
1306 * Note that this doesn't actually cover all of the multiplication instructions
1307 * available in ARM, but all of the ones that are in this space. This includes
1308 * the following instructions:
1309 *
1310 *
1311 * There are three basic encoding formats:
1312 *
1313 * Multipy (acc):
1314 * 31 - 28|27 - 24|23|22|21|20|19-16|15-12|11-8 |7|6|5|4|3-0
1315 * [ cond | 0 |0 |0 | A |S |Rn | Rd |Rs |1|0|0|1|Rm ]
1316 *
1317 * Unsigned multipy acc acc long
1318 * 31 - 28|27 - 24|23|22|21|20|19-16|15-12|11-8 |7|6|5|4|3-0
1319 * [ cond | 0 |0 |1 |0 |0 |RdHi |RdLo |Rs |1|0|0|1|Rm ]
1320 *
1321 * Multiply (acc) long:
1322 * 31 - 28|27 - 24|23|22|21|20|19-16|15-12|11-8 |7|6|5|4|3-0
1323 * [ cond | 0 |1 |Un|A |S |RdHi| RdLo |Rs |1|0|0|1|Rm ]
1324 *
1325 * A bit: Accumulate
1326 * Un bit: Unsigned is active low, signed is active high
1327 * S bit: Indicates whethere the status register should be updated.
1328 *
1329 * MLA(S) and MUL(S) make up the first type of instructions.
1330 * UMAAL makes up the second group.
1331 * (U|S)MULL(S), (U|S)MLAL(S), Make up the third.
1332 */
1333 static int
1334 arm_dis_extmul(uint32_t in, char *buf, size_t buflen)
1335 {
1336 arm_cond_code_t cc;
1337 arm_reg_t rd, rn, rs, rm;
1338 size_t len;
1339
1340 /*
1341 * RdHi is equal to rd here. RdLo is equal to Rn here.
1342 */
1343 rd = (in & ARM_EMULT_RD_MASK) >> ARM_EMULT_RD_SHIFT;
1344 rn = (in & ARM_EMULT_RN_MASK) >> ARM_EMULT_RN_SHIFT;
1345 rs = (in & ARM_EMULT_RS_MASK) >> ARM_EMULT_RS_SHIFT;
1346 rm = in & ARM_EMULT_RM_MASK;
1347
1348 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
1349
1350 if ((in & ARM_EMULT_MA_MASK) == 0) {
1351 if (in & ARM_EMULT_ABIT_MASK) {
1352 len = snprintf(buf, buflen, "mla%s%s %s, %s, %s, %s",
1353 arm_cond_names[cc],
1354 (in & ARM_EMULT_SBIT_MASK) ? "s" : "",
1355 arm_reg_names[rd], arm_reg_names[rm],
1356 arm_reg_names[rs], arm_reg_names[rs]);
1357 } else {
1358 len = snprintf(buf, buflen, "mul%s%s %s, %s, %s",
1359 arm_cond_names[cc],
1360 (in & ARM_EMULT_SBIT_MASK) ? "s" : "",
1361 arm_reg_names[rd], arm_reg_names[rm],
1362 arm_reg_names[rs]);
1363
1364 }
1365 } else if ((in & ARM_EMULT_UMA_MASK) == ARM_EMULT_UMA_TARG) {
1366 len = snprintf(buf, buflen, "umaal%s %s, %s, %s, %s",
1367 arm_cond_names[cc], arm_reg_names[rn], arm_reg_names[rd],
1368 arm_reg_names[rm], arm_reg_names[rs]);
1369 } else if ((in & ARM_EMULT_MAL_MASK) == ARM_EMULT_MAL_TARG) {
1370 len = snprintf(buf, buflen, "%s%s%s%s %s, %s, %s, %s",
1371 (in & ARM_EMULT_UNBIT_MASK) ? "s" : "u",
1372 (in & ARM_EMULT_ABIT_MASK) ? "mlal" : "mull",
1373 arm_cond_names[cc],
1374 (in & ARM_EMULT_SBIT_MASK) ? "s" : "",
1375 arm_reg_names[rn], arm_reg_names[rd], arm_reg_names[rm],
1376 arm_reg_names[rs]);
1377 } else {
1378 /* Not a supported instruction in this space */
1379 return (-1);
1380 }
1381 return (len >= buflen ? -1 : 0);
1382 }
1383
1384 /*
1385 * Here we handle the three different cases of moving to and from the various
1386 * status registers in both register mode and in immediate mode.
1387 */
1388 static int
1389 arm_dis_status_regs(uint32_t in, char *buf, size_t buflen)
1390 {
1391 arm_cond_code_t cc;
1392 arm_reg_t rd, rm;
1393 uint8_t field;
1394 int imm;
1395 size_t len;
1396
1397 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
1398
1399 if ((in & ARM_CDSP_MRS_MASK) == ARM_CDSP_MRS_TARG) {
1400 rd = (in & ARM_CDSP_RD_MASK) >> ARM_CDSP_RD_SHIFT;
1401 if (snprintf(buf, buflen, "mrs%s %s, %s", arm_cond_names[cc],
1402 arm_reg_names[rd],
1403 (in & ARM_CDSP_STATUS_RBIT) != 0 ? "spsr" : "cpsr") >=
1404 buflen)
1405 return (-1);
1406 return (0);
1407 }
1408
1409 field = (in & ARM_CDSP_MSR_F_MASK) >> ARM_CDSP_MSR_F_SHIFT;
1410 len = snprintf(buf, buflen, "msr%s %s_%s, ", arm_cond_names[cc],
1411 (in & ARM_CDSP_STATUS_RBIT) != 0 ? "spsr" : "cpsr",
1412 arm_cdsp_msr_field_names[field]);
1413 if (len >= buflen)
1414 return (-1);
1415
1416 if (in & ARM_CDSP_MSR_ISIMM_MASK) {
1417 imm = in & ARM_CDSP_MSR_IMM_MASK;
1418 imm <<= (in & ARM_CDSP_MSR_RI_MASK) >> ARM_CDSP_MSR_RI_SHIFT;
1419 len += snprintf(buf + len, buflen - len, "#%d", imm);
1420 } else {
1421 rm = in & ARM_CDSP_RM_MASK;
1422 len += snprintf(buf + len, buflen - len, "%s",
1423 arm_reg_names[rm]);
1424 }
1425
1426 return (len >= buflen ? -1 : 0);
1427 }
1428
1429 /*
1430 * Here we need to handle the Control And DSP instruction extension space. This
1431 * consists of several different instructions. Unlike other extension spaces
1432 * there isn't as much tha tis similar here as there is stuff that is different.
1433 * Oh well, that's a part of life. Instead we do a little bit of additional
1434 * parsing here.
1435 *
1436 * The first group that we separate out are the instructions that interact with
1437 * the status registers. Those are handled in their own function.
1438 */
1439 static int
1440 arm_dis_cdsp_ext(uint32_t in, char *buf, size_t buflen)
1441 {
1442 uint16_t imm, op;
1443 arm_cond_code_t cc;
1444 arm_reg_t rd, rm, rn, rs;
1445 size_t len;
1446
1447 if ((in & ARM_CDSP_STATUS_MASK) == ARM_CDSP_STATUS_TARG)
1448 return (arm_dis_status_regs(in, buf, buflen));
1449
1450 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
1451
1452 /*
1453 * This gets the Branch/exchange as well as the Branch and link/exchange
1454 * pieces. These generally also transform the instruction set into
1455 * something we can't actually disassemble. Here the lower mask and
1456 * target is the opposite. eg. the target bits are not what we want.
1457 */
1458 if ((in & ARM_CDSP_BEX_UP_MASK) == ARM_CDSP_BEX_UP_TARG &&
1459 (in & ARM_CDSP_BEX_LOW_MASK) != ARM_CDSP_BEX_NLOW_TARG) {
1460 rm = in & ARM_CDSP_RM_MASK;
1461 imm = (in & ARM_CDSP_BEX_TYPE_MASK) >> ARM_CDSP_BEX_TYPE_SHIFT;
1462 if (snprintf(buf, buflen, "b%s%s %s",
1463 imm == ARM_CDSP_BEX_TYPE_X ? "x" :
1464 imm == ARM_CDSP_BEX_TYPE_J ? "xj" : "lx",
1465 arm_cond_names[cc], arm_reg_names[rm]) >= buflen)
1466 return (-1);
1467 return (0);
1468 }
1469
1470 /* Count leading zeros */
1471 if ((in & ARM_CDSP_CLZ_MASK) == ARM_CDSP_CLZ_TARG) {
1472 rd = (in & ARM_CDSP_RD_MASK) >> ARM_CDSP_RD_SHIFT;
1473 rm = in & ARM_CDSP_RM_MASK;
1474 if (snprintf(buf, buflen, "clz%s %s, %s", arm_cond_names[cc],
1475 arm_reg_names[rd], arm_reg_names[rm]) >= buflen)
1476 return (-1);
1477 return (0);
1478 }
1479
1480 if ((in & ARM_CDSP_SAT_MASK) == ARM_CDSP_SAT_TARG) {
1481 rd = (in & ARM_CDSP_RD_MASK) >> ARM_CDSP_RD_SHIFT;
1482 rn = (in & ARM_CDSP_RN_MASK) >> ARM_CDSP_RN_SHIFT;
1483 rm = in & ARM_CDSP_RM_MASK;
1484 imm = (in & ARM_CDSP_SAT_OP_MASK) >> ARM_CDSP_SAT_OP_SHIFT;
1485 if (snprintf(buf, buflen, "q%s%s %s, %s, %s",
1486 arm_cdsp_sat_opnames[imm], arm_cond_names[cc],
1487 arm_reg_names[rd], arm_reg_names[rm],
1488 arm_reg_names[rn]) >= buflen)
1489 return (-1);
1490 return (0);
1491 }
1492
1493 /*
1494 * Breakpoint instructions are a bit different. While they are in the
1495 * conditional instruction namespace, they actually aren't defined to
1496 * take a condition. That's just how it rolls. The breakpoint is a
1497 * 16-bit value. The upper 12 bits are stored together and the lower
1498 * four together.
1499 */
1500 if ((in & ARM_CDSP_BKPT_MASK) == ARM_CDSP_BKPT_TARG) {
1501 if (cc != ARM_COND_NACC)
1502 return (-1);
1503 imm = (in & ARM_CDSP_BKPT_UIMM_MASK) >>
1504 ARM_CDSP_BKPT_UIMM_SHIFT;
1505 imm <<= 4;
1506 imm |= (in & ARM_CDSP_BKPT_LIMM_MASK);
1507 if (snprintf(buf, buflen, "bkpt %d", imm) >= buflen)
1508 return (1);
1509 return (0);
1510 }
1511
1512 /*
1513 * Here we need to handle another set of multiplies. Specifically the
1514 * Signed multiplies. This is SMLA<x><y>, SMLAW<y>, SMULW<y>,
1515 * SMLAL<x><y>, SMUL<x><y>. These instructions all follow the form:
1516 *
1517 * 31 - 28|27-25|24|23|22-21|20|19-16|15-12|11 - 8|7|6|5|4|3-0
1518 * [ cond | 0 | 1| 0| op. | 0|Rn |Rd |Rs |1|y|x|0|Rm ]
1519 *
1520 * If x is one a T is used for that part of the name. Otherwise a B is.
1521 * The same holds true for y.
1522 *
1523 * These instructions map to the following opcodes:
1524 * SMLA<x><y>: 00,
1525 * SMLAW<y>: 01 and x is zero,
1526 * SMULW<y>: 01 and x is one ,
1527 * SMLAL<x><y>: 10,
1528 * SMUL<xy><y>: 11
1529 */
1530 if ((in & ARM_CDSP_SMUL_MASK) == ARM_CDSP_SMUL_TARG) {
1531 rd = (in & ARM_CDSP_RD_MASK) >> ARM_CDSP_RD_SHIFT;
1532 rn = (in & ARM_CDSP_RN_MASK) >> ARM_CDSP_RN_SHIFT;
1533 rs = (in & ARM_CDSP_RS_MASK) >> ARM_CDSP_RS_SHIFT;
1534 rm = in & ARM_CDSP_RM_MASK;
1535 op = (in & ARM_CDSP_SMUL_OP_MASK) >> ARM_CDSP_SMUL_OP_SHIFT;
1536
1537 switch (op) {
1538 case 0:
1539 len = snprintf(buf, buflen, "smla%s%s%s %s, %s, %s, %s",
1540 (in & ARM_CDSP_SMUL_X_MASK) != 0 ? "t" : "b",
1541 (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "t" : "b",
1542 arm_cond_names[cc], arm_reg_names[rd],
1543 arm_reg_names[rm], arm_reg_names[rs],
1544 arm_reg_names[rn]);
1545 break;
1546 case 1:
1547 if (in & ARM_CDSP_SMUL_X_MASK) {
1548 len = snprintf(buf, buflen,
1549 "smulw%s%s %s, %s, %s",
1550 (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "t" :
1551 "b", arm_cond_names[cc], arm_reg_names[rd],
1552 arm_reg_names[rm], arm_reg_names[rs]);
1553 } else {
1554 len = snprintf(buf, buflen,
1555 "smlaw%s%s %s, %s, %s %s",
1556 (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "t" :
1557 "b", arm_cond_names[cc], arm_reg_names[rd],
1558 arm_reg_names[rm], arm_reg_names[rs],
1559 arm_reg_names[rn]);
1560 }
1561 break;
1562 case 2:
1563 len = snprintf(buf, buflen,
1564 "smlal%s%s%s %s, %s, %s, %s",
1565 (in & ARM_CDSP_SMUL_X_MASK) != 0 ? "t" : "b",
1566 (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "t" : "b",
1567 arm_cond_names[cc], arm_reg_names[rd],
1568 arm_reg_names[rn], arm_reg_names[rm],
1569 arm_reg_names[rs]);
1570 break;
1571 case 3:
1572 len = snprintf(buf, buflen, "smul%s%s%s %s, %s, %s",
1573 (in & ARM_CDSP_SMUL_X_MASK) != 0 ? "t" : "b",
1574 (in & ARM_CDSP_SMUL_Y_MASK) != 0 ? "t" : "b",
1575 arm_cond_names[cc], arm_reg_names[rd],
1576 arm_reg_names[rm], arm_reg_names[rs]);
1577 break;
1578 default:
1579 return (-1);
1580 }
1581 return (len >= buflen ? -1 : 0);
1582 }
1583
1584 /*
1585 * If we got here then this is some other instructin we don't know
1586 * about in the instruction extensino space.
1587 */
1588 return (-1);
1589 }
1590
1591 /*
1592 * Coprocessor double register transfers
1593 *
1594 * MCRR:
1595 * 31 - 28|27-25|24|23|22|21|20|19-16|15-12|11-8|7-4|3-0
1596 * [ cond |1 1 0| 0| 0| 1| 0| 0| Rn | Rd |cp #|op |CRm
1597 *
1598 * MRRC:
1599 * 31 - 28|27-25|24|23|22|21|20|19-16|15-12|11-8|7-4|3-0
1600 * [ cond |1 1 0| 0| 0| 1| 0| 1| Rn | Rd |cp #|op |CRm
1601 *
1602 */
1603 static int
1604 arm_dis_coproc_drt(uint32_t in, char *buf, size_t buflen)
1605 {
1606 arm_cond_code_t cc;
1607 arm_reg_t rd, rn, rm;
1608 uint8_t coproc, op;
1609 const char *ccn;
1610 size_t len;
1611
1612 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
1613 coproc = (in & ARM_COPROC_NUM_MASK) >> ARM_COPROC_NUM_SHIFT;
1614 rn = (in & ARM_COPROC_RN_MASK) >> ARM_COPROC_RN_SHIFT;
1615 rd = (in & ARM_COPROC_RD_MASK) >> ARM_COPROC_RD_SHIFT;
1616 rm = in & ARM_COPROC_RM_MASK;
1617 op = (in & ARM_COPROC_DRT_OP_MASK) >> ARM_COPROC_DRT_OP_SHIFT;
1618
1619 if (cc == ARM_COND_NACC)
1620 ccn = "2";
1621 else
1622 ccn = arm_cond_names[cc];
1623
1624 len = snprintf(buf, buflen, "%s%s %s, #%d, %s, %s, c%s",
1625 (in & ARM_COPROC_DRT_DIR_MASK) != 0 ? "mrrc" : "mcrr",
1626 ccn, arm_coproc_names[coproc], op, arm_reg_names[rd],
1627 arm_reg_names[rn], arm_reg_names[rm]);
1628 return (len >= buflen ? -1 : 0);
1629 }
1630
1631 /*
1632 * This serves as both the entry point for the normal load and stores as well as
1633 * the double register transfers (MCRR and MRCC). If it is a register transfer
1634 * then we quickly send it off.
1635 * LDC:
1636 * 31 - 28|27-25|24|23|22|21|20|19-16|15-12|11 - 8|7 - 0
1637 * [ cond |1 1 0| P| U| N| W| L| Rn | CRd | cp # | off ]
1638 *
1639 * STC:
1640 * 31 - 28|27-25|24|23|22|21|20|19-16|15-12|11 - 8|7 - 0
1641 * [ cond |1 1 0| P| U| N| W| L| Rn | CRd | cp # | off ]
1642 *
1643 * Here the bits mean:
1644 *
1645 * P bit: If P is zero, it is post-indexed or unindexed based on W. If P is 1
1646 * then it is offset-addressing or pre-indexed based on W again.
1647 *
1648 * U bit: If U is positive then the offset if added, subtracted otherwise.. Note
1649 * that if P is zero and W is zero, U must be one.
1650 *
1651 * N bit: If set that means that we have a Long size, this bit is set by the L
1652 * suffix, not to be confused with the L bit.
1653 *
1654 * W bit: If W is one then the memory address is written back to the base
1655 * register. Further W = 0 and P = 0 is unindexed addressing. W = 1, P = 0 is
1656 * post-indexed. W = 0, P = 1 is offset addressing and W = 1, P = 1 is
1657 * pre-indexed.
1658 */
1659 static int
1660 arm_dis_coproc_lsdrt(uint32_t in, char *buf, size_t buflen)
1661 {
1662 arm_cond_code_t cc;
1663 arm_reg_t rn, rd;
1664 uint8_t coproc;
1665 uint32_t imm;
1666 int pbit, ubit, nbit, wbit, lbit;
1667 const char *ccn;
1668 size_t len;
1669
1670 if ((in & ARM_COPROC_DRT_MASK) == ARM_COPROC_DRT_TARG)
1671 return (arm_dis_coproc_drt(in, buf, buflen));
1672
1673 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
1674 coproc = (in & ARM_COPROC_NUM_MASK) >> ARM_COPROC_NUM_SHIFT;
1675 rn = (in & ARM_COPROC_RN_MASK) >> ARM_COPROC_RN_SHIFT;
1676 rd = (in & ARM_COPROC_RD_MASK) >> ARM_COPROC_RD_SHIFT;
1677 imm = in & ARM_COPROC_LS_IMM_MASK;
1678
1679 pbit = in & ARM_COPROC_LS_P_MASK;
1680 ubit = in & ARM_COPROC_LS_U_MASK;
1681 nbit = in & ARM_COPROC_LS_N_MASK;
1682 wbit = in & ARM_COPROC_LS_W_MASK;
1683 lbit = in & ARM_COPROC_LS_L_MASK;
1684
1685 if (cc == ARM_COND_NACC)
1686 ccn = "2";
1687 else
1688 ccn = arm_cond_names[cc];
1689
1690 len = snprintf(buf, buflen, "%s%s%s %s, c%s, ",
1691 lbit != 0 ? "ldc" : "stc", ccn, nbit != 0 ? "l" : "",
1692 arm_coproc_names[coproc], arm_reg_names[rd]);
1693 if (len >= buflen)
1694 return (-1);
1695
1696 if (pbit != 0) {
1697 imm *= 4;
1698 len += snprintf(buf + len, buflen - len, "[%s, #%s%d]%s",
1699 arm_reg_names[rn],
1700 ubit != 0 ? "" : "-", imm,
1701 wbit != 0 ? "!" : "");
1702 } else if (wbit != 0) {
1703 imm *= 4;
1704 len += snprintf(buf + len, buflen - len, "[%s], #%s%d",
1705 arm_reg_names[rn], ubit != 0 ? "" : "-", imm);
1706 } else {
1707 len += snprintf(buf + len, buflen - len, "[%s], { %d }",
1708 arm_reg_names[rn], imm);
1709 }
1710 return (len >= buflen ? -1 : 0);
1711 }
1712
1713 /*
1714 * Here we tell a coprocessor to do data processing
1715 *
1716 * CDP:
1717 * 31 - 28|27 - 24|23-20|19-16|15-12|11 - 8|7 - 5|4|3-0
1718 * [ cond |1 1 1 0| op_1| CRn | CRd | cp # | op_2|0|CRm ]
1719 */
1720 static int
1721 arm_dis_coproc_dp(uint32_t in, char *buf, size_t buflen)
1722 {
1723 arm_cond_code_t cc;
1724 arm_reg_t rn, rd, rm;
1725 uint8_t op1, op2, coproc;
1726 const char *ccn;
1727
1728 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
1729 coproc = (in & ARM_COPROC_NUM_MASK) >> ARM_COPROC_NUM_SHIFT;
1730 rn = (in & ARM_COPROC_RN_MASK) >> ARM_COPROC_RN_SHIFT;
1731 rd = (in & ARM_COPROC_RD_MASK) >> ARM_COPROC_RD_SHIFT;
1732 rm = in & ARM_COPROC_RM_MASK;
1733 op1 = (in & ARM_COPROC_CDP_OP1_MASK) >> ARM_COPROC_CDP_OP1_SHIFT;
1734 op2 = (in & ARM_COPROC_CDP_OP2_MASK) >> ARM_COPROC_CDP_OP2_SHIFT;
1735
1736 /*
1737 * This instruction is valid with the undefined condition code. When it
1738 * does that, the instruction is intead CDP2 as opposed to CDP.
1739 */
1740 if (cc == ARM_COND_NACC)
1741 ccn = "2";
1742 else
1743 ccn = arm_cond_names[cc];
1744
1745 if (snprintf(buf, buflen, "cdp%s %s, #%d, c%s, c%s, c%s, #%d", ccn,
1746 arm_coproc_names[coproc], op1, arm_reg_names[rd],
1747 arm_reg_names[rn], arm_reg_names[rm], op2) >= buflen)
1748 return (-1);
1749
1750 return (0);
1751 }
1752
1753 /*
1754 * Here we handle coprocesser single register transfers.
1755 *
1756 * MCR:
1757 * 31 - 28|27 - 24|23-21|20|19-16|15-12|11 - 8|7 - 5|4|3-0
1758 * [ cond |1 1 1 0| op_1| 0| CRn | Rd | cp # | op_2|1|CRm ]
1759 *
1760 * MRC:
1761 * 31 - 28|27 - 24|23-21|20|19-16|15-12|11 - 8|7 - 5|4|3-0
1762 * [ cond |1 1 1 0| op_1| 1| CRn | Rd | cp # | op_2|1|CRm ]
1763 */
1764 static int
1765 arm_dis_coproc_rt(uint32_t in, char *buf, size_t buflen)
1766 {
1767 arm_cond_code_t cc;
1768 arm_reg_t rn, rd, rm;
1769 uint8_t op1, op2, coproc;
1770 const char *ccn;
1771 size_t len;
1772
1773 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
1774 coproc = (in & ARM_COPROC_NUM_MASK) >> ARM_COPROC_NUM_SHIFT;
1775 rn = (in & ARM_COPROC_RN_MASK) >> ARM_COPROC_RN_SHIFT;
1776 rd = (in & ARM_COPROC_RD_MASK) >> ARM_COPROC_RD_SHIFT;
1777 rm = in & ARM_COPROC_RM_MASK;
1778 op1 = (in & ARM_COPROC_CRT_OP1_MASK) >> ARM_COPROC_CRT_OP1_SHIFT;
1779 op2 = (in & ARM_COPROC_CRT_OP2_MASK) >> ARM_COPROC_CRT_OP2_SHIFT;
1780
1781 if (cc == ARM_COND_NACC)
1782 ccn = "2";
1783 else
1784 ccn = arm_cond_names[cc];
1785
1786 len = snprintf(buf, buflen, "%s%s %s, #%d, %s, c%s, c%s",
1787 (in & ARM_COPROC_CRT_DIR_MASK) != 0 ? "mrc" : "mcr", ccn,
1788 arm_coproc_names[coproc], op1, arm_reg_names[rd],
1789 arm_reg_names[rn], arm_reg_names[rm]);
1790 if (len >= buflen)
1791 return (-1);
1792
1793 if (op2 != 0)
1794 if (snprintf(buf + len, buflen - len, ", #%d", op2) >=
1795 buflen - len)
1796 return (-1);
1797 return (0);
1798 }
1799
1800 /*
1801 * Here we handle the set of unconditional instructions.
1802 */
1803 static int
1804 arm_dis_uncond_insn(uint32_t in, char *buf, size_t buflen)
1805 {
1806 int imm, sc;
1807 arm_reg_t rn, rm;
1808 size_t len;
1809
1810 /*
1811 * The CPS instruction is a bit complicated. It has the following big
1812 * pattern which maps to a few different ways to use it:
1813 *
1814 *
1815 * 31-28|27-25|24|23-20|19-18|17 |16|15-9|8|7|6|5|4-0
1816 * 1 | 0 | 1| 0 |imod|mmod| 0|SBZ |A|I|F|0|mode
1817 *
1818 * CPS<effect> <iflags> {, #<mode> }
1819 * CPS #<mode>
1820 *
1821 * effect: determines what to do with the A, I, F interrupt bits in the
1822 * CPSR. effect is encoded in the imod field. It is either enable
1823 * interrupts 0b10 or disable interrupts 0b11. Recall that interrupts
1824 * are active low in the CPSR. If effect is not specified then this is
1825 * strictly a mode change which is required.
1826 *
1827 * A, I, F: If effect is specified then the bits which are high are
1828 * modified by the instruction.
1829 *
1830 * mode: Specifies a mode to change to. mmod will be 1 if mode is set.
1831 *
1832 */
1833 if ((in & ARM_UNI_CPS_MASK) == ARM_UNI_CPS_TARG) {
1834 imm = (in & ARM_UNI_CPS_IMOD_MASK) > ARM_UNI_CPS_IMOD_SHIFT;
1835
1836 /* Ob01 is not a valid value for the imod */
1837 if (imm == 1)
1838 return (-1);
1839
1840 if (imm != 0)
1841 len = snprintf(buf, buflen, "cps%s %s%s%s%s",
1842 imm == 2 ? "ie" : "id",
1843 (in & ARM_UNI_CPS_A_MASK) ? "a" : "",
1844 (in & ARM_UNI_CPS_I_MASK) ? "i" : "",
1845 (in & ARM_UNI_CPS_F_MASK) ? "f" : "",
1846 (in & ARM_UNI_CPS_MMOD_MASK) ? " ," : "");
1847 else
1848 len = snprintf(buf, buflen, "cps ");
1849 if (len >= buflen)
1850 return (-1);
1851
1852 if (in & ARM_UNI_CPS_MMOD_MASK)
1853 if (snprintf(buf + len, buflen - len, "#%d",
1854 in & ARM_UNI_CPS_MODE_MASK) >= buflen - len)
1855 return (-1);
1856 return (0);
1857 }
1858
1859 if ((in & ARM_UNI_SE_MASK) == ARM_UNI_SE_TARG) {
1860 if (snprintf(buf, buflen, "SETEND %s",
1861 (in & ARM_UNI_SE_BE_MASK) ? "be" : "le") >= buflen)
1862 return (-1);
1863 return (0);
1864 }
1865
1866 /*
1867 * The cache preload is like a load, but it has a much simpler set of
1868 * constraints. The only valid bits that you can transform are the I and
1869 * the U bits. We have to use pre-indexed addressing. This means that we
1870 * only have the U bit and the I bit. See arm_dis_ldstr for a full
1871 * explanation of what's happening here.
1872 */
1873 if ((in & ARM_UNI_PLD_MASK) == ARM_UNI_PLD_TARG) {
1874 rn = (in & ARM_LS_RN_MASK) >> ARM_LS_RN_SHIFT;
1875 if ((in & ARM_LS_IBIT_MASK) == 0) {
1876 if (snprintf(buf, buflen, "pld [%s, #%s%d",
1877 arm_reg_names[rn],
1878 (in & ARM_LS_UBIT_MASK) != 0 ? "" : "-",
1879 in & ARM_LS_IMM_MASK) >= buflen)
1880 return (-1);
1881 return (0);
1882 }
1883
1884 rm = in & ARM_LS_REG_RM_MASK;
1885 len = snprintf(buf, buflen, "pld [%s, %s%s", arm_reg_names[rn],
1886 (in & ARM_LS_UBIT_MASK) != 0 ? "" : "-",
1887 arm_reg_names[rm]);
1888 if (len >= buflen)
1889 return (-1);
1890
1891 if ((in & ARM_LS_REG_NRM_MASK) != 0) {
1892 imm = (in & ARM_LS_SCR_SIMM_MASK) >>
1893 ARM_LS_SCR_SIMM_SHIFT;
1894 sc = (in & ARM_LS_SCR_SCODE_MASK) >>
1895 ARM_LS_SCR_SCODE_SHIFT;
1896
1897 if (imm == 0 && sc == DPI_S_ROR)
1898 sc = DPI_S_RRX;
1899
1900 len += snprintf(buf + len, buflen - len, "%s",
1901 arm_dpi_shifts[sc]);
1902 if (len >= buflen)
1903 return (-1);
1904 if (sc != DPI_S_RRX) {
1905 len += snprintf(buf + len, buflen - len,
1906 " #%d", imm);
1907 if (len >= buflen)
1908 return (-1);
1909 }
1910 }
1911 if (snprintf(buf + len, buflen - len, "]") >= buflen - len)
1912 return (-1);
1913 return (0);
1914 }
1915
1916 /*
1917 * This is a special case of STM, but it works across chip modes.
1918 */
1919 if ((in & ARM_UNI_SRS_MASK) == ARM_UNI_SRS_TARG) {
1920 imm = (in & ARM_LSM_ADDR_MASK) >> ARM_LSM_ADDR_SHIFT;
1921 if (snprintf(buf, buflen, "srs%s #%d%s",
1922 arm_lsm_mode_names[imm],
1923 in & ARM_UNI_SRS_MODE_MASK,
1924 (in & ARM_UNI_SRS_WBIT_MASK) != 0 ? "!" : "") >= buflen)
1925 return (-1);
1926 return (0);
1927 }
1928
1929 /*
1930 * RFE is a return from exception instruction that is similar to the LDM
1931 * and STM, but a bit different.
1932 */
1933 if ((in & ARM_UNI_RFE_MASK) == ARM_UNI_RFE_TARG) {
1934 imm = (in & ARM_LSM_ADDR_MASK) >> ARM_LSM_ADDR_SHIFT;
1935 rn = (in & ARM_LS_RN_MASK) >> ARM_LS_RN_SHIFT;
1936 if (snprintf(buf, buflen, "rfe%s %s%s", arm_lsm_mode_names[imm],
1937 arm_reg_names[rn],
1938 (in & ARM_UNI_RFE_WBIT_MASK) != 0 ? "!" : "") >= buflen)
1939 return (-1);
1940 return (0);
1941 }
1942
1943 if ((in & ARM_UNI_BLX_MASK) == ARM_UNI_BLX_TARG) {
1944 if (snprintf(buf, buflen, "blx %d",
1945 in & ARM_UNI_BLX_IMM_MASK) >= buflen)
1946 return (-1);
1947 return (0);
1948 }
1949
1950 if ((in & ARM_UNI_CODRT_MASK) == ARM_UNI_CODRT_TARG) {
1951 return (arm_dis_coproc_lsdrt(in, buf, buflen));
1952 }
1953
1954 if ((in & ARM_UNI_CORT_MASK) == ARM_UNI_CORT_TARG) {
1955 return (arm_dis_coproc_rt(in, buf, buflen));
1956 }
1957
1958 if ((in & ARM_UNI_CODP_MASK) == ARM_UNI_CORT_TARG) {
1959 return (arm_dis_coproc_dp(in, buf, buflen));
1960 }
1961
1962 /*
1963 * An undefined or illegal instruction
1964 */
1965 return (-1);
1966 }
1967
1968 /*
1969 * Disassemble B and BL instructions. The instruction is given a 24-bit two's
1970 * complement value as an offset address. This value gets sign extended to 30
1971 * bits and then shifted over two bits. This is then added to the PC + 8. So,
1972 * instead of dispalying an absolute address, we're going to display the delta
1973 * that the instruction has instead.
1974 */
1975 static int
1976 arm_dis_branch(dis_handle_t *dhp, uint32_t in, char *buf, size_t buflen)
1977 {
1978 uint32_t addr;
1979 arm_cond_code_t cc;
1980 size_t len;
1981
1982 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
1983 addr = in & ARM_BRANCH_IMM_MASK;
1984 if (in & ARM_BRANCH_SIGN_MASK)
1985 addr |= ARM_BRANCH_NEG_SIGN;
1986 else
1987 addr &= ARM_BRANCH_POS_SIGN;
1988 addr <<= 2;
1989 if ((len = snprintf(buf, buflen, "b%s%s %d",
1990 (in & ARM_BRANCH_LBIT_MASK) != 0 ? "l" : "",
1991 arm_cond_names[cc], (int)addr)) >= buflen)
1992 return (-1);
1993
1994 /* Per the ARM manuals, we have to account for the extra 8 bytes here */
1995 if (dhp->dh_lookup(dhp->dh_data, dhp->dh_addr + (int)addr + 8, NULL, 0,
1996 NULL, NULL) == 0) {
1997 len += snprintf(buf + len, buflen - len, "\t<");
1998 if (len >= buflen)
1999 return (-1);
2000 dhp->dh_lookup(dhp->dh_data, dhp->dh_addr + (int)addr + 8,
2001 buf + len, buflen - len, NULL, NULL);
2002 strlcat(buf, ">", buflen);
2003 }
2004
2005 return (0);
2006 }
2007
2008 /*
2009 * There are six instructions that are covered here: ADD16, ADDSUBX, SUBADDX,
2010 * SUB16, ADD8, and SUB8. They can hae the following variations: S, Q, SH, U,
2011 * UQ, and UH. It has two differnt sets of bits to determine the opcode: 22-20
2012 * and then 7-5.
2013 *
2014 * These instructions have the general form of:
2015 *
2016 * 31 - 28|27-25|24|23|22-20|19-16|15-12|11 - 8|7-5|4|3-0
2017 * [ cond |0 1 1| 0| 0| opP |Rn |Rd |SBO |opI|1|Rm ]
2018 *
2019 * Here we use opP to refer to the prefix of the instruction, eg. S, Q, etc.
2020 * Where as opI refers to which instruction it is, eg. ADD16, ADD8, etc. We use
2021 * string tables for both of these in arm_padd_p_names and arm_padd_i_names. If
2022 * there is an empty entry that means that the instruction in question doesn't
2023 * exist.
2024 */
2025 static int
2026 arm_dis_padd(uint32_t in, char *buf, size_t buflen)
2027 {
2028 arm_reg_t rn, rd, rm;
2029 arm_cond_code_t cc;
2030 uint8_t opp, opi;
2031 const char *pstr, *istr;
2032
2033 opp = (in & ARM_MEDIA_OP1_MASK) >> ARM_MEDIA_OP1_SHIFT;
2034 opi = (in & ARM_MEDIA_OP2_MASK) >> ARM_MEDIA_OP2_SHIFT;
2035
2036 pstr = arm_padd_p_names[opp];
2037 istr = arm_padd_i_names[opi];
2038
2039 if (pstr == NULL || istr == NULL)
2040 return (-1);
2041
2042 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
2043 rn = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT;
2044 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT;
2045 rm = in & ARM_MEDIA_RM_MASK;
2046
2047 if (snprintf(buf, buflen, "%s%%s %s, %s, %s", pstr, istr,
2048 arm_cond_names[cc], arm_reg_names[rd], arm_reg_names[rn],
2049 arm_reg_names[rm]) >= buflen)
2050 return (-1);
2051 return (0);
2052 }
2053
2054 /*
2055 * Disassemble the extend instructions from ARMv6. There are six instructions:
2056 *
2057 * XTAB16, XTAB, XTAH, XTB16, XTB, XTFH. These can exist with one of the
2058 * following prefixes: S, U. The opcode exists in bits 22-20. We have the
2059 * following rules from there:
2060 *
2061 * If bit 22 is one then we are using the U prefix, otherwise the S prefix. Then
2062 * we have the following opcode maps in the lower two bits:
2063 * XTAB16 00 iff Rn != 0xf
2064 * XTAB 10 iff Rn != 0xf
2065 * XTAH 11 iff Rn != 0xf
2066 * XTB16 00 iff Rn = 0xf
2067 * XTB 10 iff Rn = 0xf
2068 * XTH 11 iff Rn = 0xf
2069 */
2070 static int
2071 arm_dis_extend(uint32_t in, char *buf, size_t buflen)
2072 {
2073 uint8_t op, rot;
2074 int sbit;
2075 arm_cond_code_t cc;
2076 arm_reg_t rn, rm, rd;
2077 const char *opn;
2078 size_t len;
2079
2080
2081 rn = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT;
2082 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT;
2083 rm = in & ARM_MEDIA_RM_MASK;
2084 op = (in & ARM_MEDIA_SZE_OP_MASK) >> ARM_MEDIA_SZE_OP_SHIFT;
2085 rot = (in & ARM_MEDIA_SZE_ROT_MASK) >> ARM_MEDIA_SZE_ROT_SHIFT;
2086 sbit = in & ARM_MEDIA_SZE_S_MASK;
2087 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
2088
2089 switch (op) {
2090 case 0x0:
2091 opn = rn == ARM_REG_R15 ? "xtab16" : "xtb16";
2092 break;
2093 case 0x2:
2094 opn = rn == ARM_REG_R15 ? "xtab" : "xtb";
2095 break;
2096 case 0x3:
2097 opn = rn == ARM_REG_R15 ? "xtah" : "xth";
2098 break;
2099 default:
2100 return (-1);
2101 break;
2102 }
2103
2104 if (rn == ARM_REG_R15) {
2105 len = snprintf(buf, buflen, "%s%s%s %s, %s",
2106 sbit != 0 ? "u" : "s",
2107 opn, arm_cond_names[cc], arm_reg_names[rd],
2108 arm_reg_names[rn]);
2109 } else {
2110 len = snprintf(buf, buflen, "%s%s%s %s, %s, %s",
2111 sbit != 0 ? "u" : "s",
2112 opn, arm_cond_names[cc], arm_reg_names[rd],
2113 arm_reg_names[rn], arm_reg_names[rm]);
2114 }
2115
2116 if (len >= buflen)
2117 return (-1);
2118
2119 if (snprintf(buf + len, buflen - len, "%s",
2120 arm_extend_rot_names[rot]) >= buflen - len)
2121 return (-1);
2122 return (0);
2123 }
2124
2125 /*
2126 * The media instructions and extensions can be divided into different groups of
2127 * instructions. We first use bits 23 and 24 to figure out where to send it. We
2128 * call this group of bits the l1 mask.
2129 */
2130 static int
2131 arm_dis_media(uint32_t in, char *buf, size_t buflen)
2132 {
2133 uint8_t l1, op1, op2;
2134 arm_cond_code_t cc;
2135 arm_reg_t rd, rn, rs, rm;
2136 int xbit;
2137 size_t len;
2138
2139 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
2140 l1 = (in & ARM_MEDIA_L1_MASK) >> ARM_MEDIA_L1_SHIFT;
2141 switch (l1) {
2142 case 0x0:
2143 return (arm_dis_padd(in, buf, buflen));
2144 break;
2145 case 0x1:
2146 if ((in & ARM_MEDIA_HPACK_MASK) == ARM_MEDIA_HPACK_TARG) {
2147 rn = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT;
2148 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT;
2149 rm = in & ARM_MEDIA_RM_MASK;
2150 op1 = (in & ARM_MEDIA_HPACK_SHIFT_MASK) >>
2151 ARM_MEDIA_HPACK_SHIFT_IMM;
2152 len = snprintf(buf, buflen, "%s%s %s, %s, %s",
2153 (in & ARM_MEDIA_HPACK_OP_MASK) != 0 ?
2154 "pkhtb" : "pkhbt", arm_cond_names[cc],
2155 arm_reg_names[rd], arm_reg_names[rn],
2156 arm_reg_names[rd]);
2157 if (len >= buflen)
2158 return (-1);
2159
2160 if (op1 != 0) {
2161 if (in & ARM_MEDIA_HPACK_OP_MASK)
2162 len += snprintf(buf + len, buflen - len,
2163 ", asr %d", op1);
2164 else
2165 len += snprintf(buf + len, buflen - len,
2166 ", lsl %d", op1);
2167 }
2168 return (len >= buflen ? -1 : 0);
2169 }
2170
2171 if ((in & ARM_MEDIA_WSAT_MASK) == ARM_MEDIA_WSAT_TARG) {
2172 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT;
2173 rm = in & ARM_MEDIA_RM_MASK;
2174 op1 = (in & ARM_MEDIA_SAT_IMM_MASK) >>
2175 ARM_MEDIA_SAT_IMM_SHIFT;
2176 op2 = (in & ARM_MEDIA_SAT_SHI_MASK) >>
2177 ARM_MEDIA_SAT_SHI_SHIFT;
2178 len = snprintf(buf, buflen, "%s%s %s, #%d, %s",
2179 (in & ARM_MEDIA_SAT_U_MASK) != 0 ? "usat" : "ssat",
2180 arm_cond_names[cc], arm_reg_names[rd], op1,
2181 arm_reg_names[rm]);
2182
2183 if (len >= buflen)
2184 return (-1);
2185
2186 /*
2187 * The shift is optional in the assembler and encoded as
2188 * LSL 0. However if we get ASR 0, that means ASR #32.
2189 * An ARM_MEDIA_SAT_STYPE_MASK of 0 is LSL, 1 is ASR.
2190 */
2191 if (op2 != 0 || (in & ARM_MEDIA_SAT_STYPE_MASK) == 1) {
2192 if (op2 == 0)
2193 op2 = 32;
2194 if (snprintf(buf + len, buflen - len,
2195 ", %s #%d",
2196 (in & ARM_MEDIA_SAT_STYPE_MASK) != 0 ?
2197 "asr" : "lsl", op2) >= buflen - len)
2198 return (-1);
2199 }
2200 return (0);
2201 }
2202
2203 if ((in & ARM_MEDIA_PHSAT_MASK) == ARM_MEDIA_PHSAT_TARG) {
2204 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT;
2205 rm = in & ARM_MEDIA_RM_MASK;
2206 op1 = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT;
2207 if (snprintf(buf, buflen, "%s%s %s, #%d, %s",
2208 (in & ARM_MEDIA_SAT_U_MASK) != 0 ?
2209 "usat16" : "ssat16",
2210 arm_cond_names[cc], arm_reg_names[rd], op1,
2211 arm_reg_names[rm]) >= buflen)
2212 return (-1);
2213 return (0);
2214 }
2215
2216 if ((in & ARM_MEDIA_REV_MASK) == ARM_MEDIA_REV_TARG) {
2217 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT;
2218 rm = in & ARM_MEDIA_RM_MASK;
2219 if (snprintf(buf, buflen, "rev%s %s, %s",
2220 arm_cond_names[cc], arm_reg_names[rd],
2221 arm_reg_names[rd]) >= buflen)
2222 return (-1);
2223 return (0);
2224 }
2225
2226 if ((in & ARM_MEDIA_BRPH_MASK) == ARM_MEDIA_BRPH_TARG) {
2227 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT;
2228 rm = in & ARM_MEDIA_RM_MASK;
2229 if (snprintf(buf, buflen, "rev16%s %s, %s",
2230 arm_cond_names[cc], arm_reg_names[rd],
2231 arm_reg_names[rd]) >= buflen)
2232 return (-1);
2233 return (0);
2234 }
2235
2236 if ((in & ARM_MEDIA_BRSH_MASK) == ARM_MEDIA_BRSH_TARG) {
2237 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT;
2238 rm = in & ARM_MEDIA_RM_MASK;
2239 if (snprintf(buf, buflen, "revsh%s %s, %s",
2240 arm_cond_names[cc], arm_reg_names[rd],
2241 arm_reg_names[rd]) >= buflen)
2242 return (-1);
2243 return (0);
2244 }
2245
2246 if ((in & ARM_MEDIA_SEL_MASK) == ARM_MEDIA_SEL_TARG) {
2247 rn = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT;
2248 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT;
2249 rm = in & ARM_MEDIA_RM_MASK;
2250 if (snprintf(buf, buflen, "sel%s %s, %s, %s",
2251 arm_cond_names[cc], arm_reg_names[rd],
2252 arm_reg_names[rn], arm_reg_names[rm]) >= buflen)
2253 return (-1);
2254 return (0);
2255 }
2256
2257 if ((in & ARM_MEDIA_SZE_MASK) == ARM_MEDIA_SZE_TARG)
2258 return (arm_dis_extend(in, buf, buflen));
2259 /* Unknown instruction */
2260 return (-1);
2261 break;
2262 case 0x2:
2263 /*
2264 * This consists of the following multiply instructions:
2265 * SMLAD, SMLSD, SMLALD, SMUAD, and SMUSD.
2266 *
2267 * SMLAD and SMUAD encoding are the same, switch on Rn == R15
2268 * 22-20 are 000 7-6 are 00
2269 * SMLSD and SMUSD encoding are the same, switch on Rn == R15
2270 * 22-20 are 000 7-6 are 01
2271 * SMLALD: 22-20 are 100 7-6 are 00
2272 */
2273 rn = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT;
2274 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT;
2275 rs = (in & ARM_MEDIA_RS_MASK) >> ARM_MEDIA_RS_SHIFT;
2276 rm = in & ARM_MEDIA_RM_MASK;
2277 op1 = (in & ARM_MEDIA_OP1_MASK) >> ARM_MEDIA_OP1_SHIFT;
2278 op2 = (in & ARM_MEDIA_OP2_MASK) >> ARM_MEDIA_OP2_SHIFT;
2279 xbit = in & ARM_MEDIA_MULT_X_MASK;
2280
2281 if (op1 == 0x0) {
2282 if (op2 != 0x0 && op2 != 0x1)
2283 return (-1);
2284 if (rn == ARM_REG_R15) {
2285 len = snprintf(buf, buflen, "%s%s%s %s, %s, %s",
2286 op2 != 0 ? "smusd" : "smuad",
2287 xbit != 0 ? "x" : "x",
2288 arm_cond_names[cc], arm_reg_names[rd],
2289 arm_reg_names[rm], arm_reg_names[rs]);
2290 } else {
2291 len = snprintf(buf, buflen,
2292 "%s%s%s %s, %s, %s, %s",
2293 op2 != 0 ? "smlsd" : "smlad",
2294 xbit != 0 ? "x" : "",
2295 arm_cond_names[cc], arm_reg_names[rd],
2296 arm_reg_names[rm], arm_reg_names[rs],
2297 arm_reg_names[rn]);
2298
2299 }
2300 } else if (op1 == 0x8) {
2301 if (op2 != 0x0)
2302 return (-1);
2303 len = snprintf(buf, buflen, "smlald%s%s %s, %s, %s, %s",
2304 xbit != 0 ? "x" : "",
2305 arm_cond_names[cc], arm_reg_names[rn],
2306 arm_reg_names[rd], arm_reg_names[rm],
2307 arm_reg_names[rs]);
2308 } else
2309 return (-1);
2310
2311 return (len >= buflen ? -1 : 0);
2312 break;
2313 case 0x3:
2314 /*
2315 * Here we handle USAD8 and USADA8. The main difference is the
2316 * presence of RN. USAD8 is defined as having a value of rn that
2317 * is not r15. If it is r15, then instead it is USADA8.
2318 */
2319 if ((in & ARM_MEDIA_OP1_MASK) != 0)
2320 return (-1);
2321 if ((in & ARM_MEDIA_OP2_MASK) != 0)
2322 return (-1);
2323
2324 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
2325 rn = (in & ARM_MEDIA_RN_MASK) >> ARM_MEDIA_RN_SHIFT;
2326 rd = (in & ARM_MEDIA_RD_MASK) >> ARM_MEDIA_RD_SHIFT;
2327 rs = (in & ARM_MEDIA_RS_MASK) >> ARM_MEDIA_RS_SHIFT;
2328 rm = in & ARM_MEDIA_RM_MASK;
2329
2330 if (rn != ARM_REG_R15)
2331 len = snprintf(buf, buflen, "usada8%s %s, %s, %s, %s",
2332 arm_cond_names[cc], arm_reg_names[rd],
2333 arm_reg_names[rm], arm_reg_names[rs],
2334 arm_reg_names[rn]);
2335 else
2336 len = snprintf(buf, buflen, "usad8%s %s, %s, %s",
2337 arm_cond_names[cc], arm_reg_names[rd],
2338 arm_reg_names[rm], arm_reg_names[rs]);
2339 return (len >= buflen ? -1 : 0);
2340 break;
2341 default:
2342 return (-1);
2343 }
2344 }
2345
2346 /*
2347 * Each instruction in the ARM instruction set is a uint32_t and in our case is
2348 * LE. The upper four bits determine the condition code. If the conditoin code
2349 * is undefined then we know to immediately jump there. Otherwise we go use the
2350 * next three bits to determine where we should go next and how to further
2351 * process the instruction in question. The ARM instruction manual doesn't
2352 * define this field so we're going to call it the L1_DEC or level 1 decoding
2353 * from which it will have to be further subdivided into the specific
2354 * instruction groupings that we care about.
2355 */
2356 static int
2357 arm_dis(dis_handle_t *dhp, uint32_t in, char *buf, size_t buflen)
2358 {
2359 uint8_t l1;
2360 arm_cond_code_t cc;
2361
2362 cc = (in & ARM_CC_MASK) >> ARM_CC_SHIFT;
2363
2364 if (cc == ARM_COND_NACC)
2365 return (arm_dis_uncond_insn(in, buf, buflen));
2366
2367 l1 = (in & ARM_L1_DEC_MASK) >> ARM_L1_DEC_SHIFT;
2368
2369 switch (l1) {
2370 case 0x0:
2371 /*
2372 * The l0 group is a bit complicated. We have several different
2373 * groups of instructions to consider. The first question is
2374 * whether bit 4 is zero or not. If it is, then we have a data
2375 * processing immediate shift unless the opcode and + S bits
2376 * (24-20) is of the form 0b10xx0.
2377 *
2378 * When bit 4 is 1, we have to then also look at bit 7. If bit
2379 * 7 is one then we know that this is the class of multiplies /
2380 * extra load/stores. If bit 7 is zero then we have the same
2381 * opcode games as we did above.
2382 */
2383 if (in & ARM_L1_0_B4_MASK) {
2384 if (in & ARM_L1_0_B7_MASK) {
2385 /*
2386 * Both the multiplication extensions and the
2387 * load and store extensions live in this
2388 * region. The load and store extensions can be
2389 * identified by having at least one of bits 5
2390 * and 6 set. The exceptions to this are the
2391 * SWP and SWPB instructions and the exclusive
2392 * load and store instructions which, unlike the
2393 * multiplication instructions. These have
2394 * specific values for the bits in the range of
2395 * 20-24.
2396 */
2397 if ((in & ARM_L1_0_ELS_MASK) != 0)
2398 /* Extra loads/stores */
2399 return (arm_dis_els(in, buf, buflen));
2400 if ((in & ARM_ELS_SWAP_MASK) == ARM_ELS_IS_SWAP)
2401 return (arm_dis_swap(in, buf, buflen));
2402 if ((in & ARM_ELS_EXCL_MASK) ==
2403 ARM_ELS_EXCL_MASK)
2404 return (arm_dis_lsexcl(in, buf,
2405 buflen));
2406 /* Multiplication instruction extension A3-3. */
2407 return (arm_dis_extmul(in, buf, buflen));
2408 }
2409 if ((in & ARM_L1_0_OPMASK) == ARM_L1_0_SPECOP &&
2410 !(in & ARM_L1_0_SMASK)) {
2411 /* Misc. Instructions A3-4 */
2412 return (arm_dis_cdsp_ext(in, buf, buflen));
2413 } else {
2414 /* data processing register shift */
2415 return (arm_dis_dpi(in, cc, buf, buflen));
2416 }
2417 } else {
2418 if ((in & ARM_L1_0_OPMASK) == ARM_L1_0_SPECOP &&
2419 !(in & ARM_L1_0_SMASK))
2420 /* Misc. Instructions A3-4 */
2421 return (arm_dis_cdsp_ext(in, buf, buflen));
2422 else {
2423 /* Data processing immediate shift */
2424 return (arm_dis_dpi(in, cc, buf, buflen));
2425 }
2426 }
2427 break;
2428 case 0x1:
2429 /*
2430 * In l1 group 0b001 there are a few ways to tell things apart.
2431 * We are directed to first look at bits 20-24. Data processing
2432 * immediate has a 4 bit opcode 24-21 followed by an S bit. We
2433 * know it is not a data processing immediate if we have
2434 * something of the form 0b10xx0.
2435 */
2436 if ((in & ARM_L1_1_OPMASK) == ARM_L1_1_SPECOP &&
2437 !(in & ARM_L1_1_SMASK)) {
2438 if (in & ARM_L1_1_UNDEF_MASK) {
2439 /* Undefined instructions */
2440 return (-1);
2441 } else {
2442 /* Move immediate to status register */
2443 return (arm_dis_status_regs(in, buf, buflen));
2444 }
2445 } else {
2446 /* Data processing immedaite */
2447 return (arm_dis_dpi(in, cc, buf, buflen));
2448 }
2449 break;
2450 case 0x2:
2451 /* Load/store Immediate offset */
2452 return (arm_dis_ldstr(in, buf, buflen));
2453 break;
2454 case 0x3:
2455 /*
2456 * Like other sets we use the 4th bit to make an intial
2457 * determination. If it is zero then this is a load/store
2458 * register offset class instruction. Following that we have a
2459 * specical mask of 0x01f000f0 to determine whether this is an
2460 * architecturally undefined instruction type or not.
2461 *
2462 * The architecturally undefined are parts of the current name
2463 * space that just aren't used, but could be used at some point
2464 * in the future. For now though, it's an invalid op code.
2465 */
2466 if (in & ARM_L1_3_B4_MASK) {
2467 if ((in & ARM_L1_3_ARCHUN_MASK) ==
2468 ARM_L1_3_ARCHUN_MASK) {
2469 /* Architecturally undefined */
2470 return (-1);
2471 } else {
2472 /* Media instructions */
2473 return (arm_dis_media(in, buf, buflen));
2474 }
2475 } else {
2476 /* Load/store register offset */
2477 return (arm_dis_ldstr(in, buf, buflen));
2478 }
2479 break;
2480 case 0x4:
2481 /* Load/store multiple */
2482 return (arm_dis_ldstr_multi(in, buf, buflen));
2483 break;
2484 case 0x5:
2485 /* Branch and Branch with link */
2486 return (arm_dis_branch(dhp, in, buf, buflen));
2487 break;
2488 case 0x6:
2489 /* coprocessor load/store && double register transfers */
2490 return (arm_dis_coproc_lsdrt(in, buf, buflen));
2491 break;
2492 case 0x7:
2493 /*
2494 * In l1 group 0b111 you can determine the three groups using
2495 * the following logic. If the next bit after the l1 group (bit
2496 * 24) is one than you know that it is a software interrupt.
2497 * Otherwise it is one of the coprocessor instructions.
2498 * Furthermore you can tell apart the data processing from the
2499 * register transfers based on bit 4. If it is zero then it is
2500 * a data processing instruction, otherwise it is a register
2501 * transfer.
2502 */
2503 if (in & ARM_L1_7_SWINTMASK) {
2504 /*
2505 * The software interrupt is pretty straightforward. The
2506 * lower 24 bits are the interrupt number. It's also
2507 * valid for it to run with a condition code.
2508 */
2509 if (snprintf(buf, buflen, "swi%s %d",
2510 arm_cond_names[cc],
2511 in & ARM_SWI_IMM_MASK) >= buflen)
2512 return (-1);
2513 return (0);
2514 } else if (in & ARM_L1_7_COPROCMASK) {
2515 /* coprocessor register transfers */
2516 return (arm_dis_coproc_rt(in, buf, buflen));
2517 } else {
2518 /* coprocessor data processing */
2519 return (arm_dis_coproc_dp(in, buf, buflen));
2520 }
2521 break;
2522 }
2523
2524 return (-1);
2525 }
2526
2527 static int
2528 dis_arm_supports_flags(int flags)
2529 {
2530 int archflags = flags & DIS_ARCH_MASK;
2531
2532 return (archflags == DIS_ARM);
2533 }
2534
2535 /*ARGSUSED*/
2536 static int
2537 dis_arm_handle_attach(dis_handle_t *dhp)
2538 {
2539 return (0);
2540 }
2541
2542 /*ARGSUSED*/
2543 static void
2544 dis_arm_handle_detach(dis_handle_t *dhp)
2545 {
2546 }
2547
2548 static int
2549 dis_arm_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, size_t buflen)
2550 {
2551 uint32_t in;
2552
2553 buf[0] = '\0';
2554 dhp->dh_addr = addr;
2555 if (dhp->dh_read(dhp->dh_data, addr, &in, sizeof (in)) !=
2556 sizeof (in))
2557 return (-1);
2558
2559 /* Translate in case we're on sparc? */
2560 in = LE_32(in);
2561
2562 return (arm_dis(dhp, in, buf, buflen));
2563 }
2564
2565 /*
2566 * This is simple in a non Thumb world. If and when we do enter a world where we
2567 * support thumb instructions, then this becomes far less than simple.
2568 */
2569 /*ARGSUSED*/
2570 static uint64_t
2571 dis_arm_previnstr(dis_handle_t *dhp, uint64_t pc, int n)
2572 {
2573 if (n <= 0)
2574 return (pc);
2575
2576 return (pc - n*4);
2577 }
2578
2579 /*
2580 * If and when we support thumb, then this value should probably become two.
2581 * However, it varies based on whether or not a given instruction is in thumb
2582 * mode.
2583 */
2584 /*ARGSUSED*/
2585 static int
2586 dis_arm_min_instrlen(dis_handle_t *dhp)
2587 {
2588 return (4);
2589 }
2590
2591 /*
2592 * Regardless of thumb, this value does not change.
2593 */
2594 /*ARGSUSED*/
2595 static int
2596 dis_arm_max_instrlen(dis_handle_t *dhp)
2597 {
2598 return (4);
2599 }
2600
2601 /* ARGSUSED */
2602 static int
2603 dis_arm_instrlen(dis_handle_t *dhp, uint64_t pc)
2604 {
2605 return (4);
2606 }
2607
2608 dis_arch_t dis_arch_arm = {
2609 dis_arm_supports_flags,
2610 dis_arm_handle_attach,
2611 dis_arm_handle_detach,
2612 dis_arm_disassemble,
2613 dis_arm_previnstr,
2614 dis_arm_min_instrlen,
2615 dis_arm_max_instrlen,
2616 dis_arm_instrlen
2617 };