1 /***************************************************************************
2  *   Copyright (C) 2006 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   Copyright (C) 2009 by David Brownell                                  *
6  *                                                                         *
7  *   This program is free software; you can redistribute it and/or modify  *
8  *   it under the terms of the GNU General Public License as published by  *
9  *   the Free Software Foundation; either version 2 of the License, or     *
10  *   (at your option) any later version.                                   *
11  *                                                                         *
12  *   This program is distributed in the hope that it will be useful,       *
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
15  *   GNU General Public License for more details.                          *
16  *                                                                         *
17  *   You should have received a copy of the GNU General Public License     *
18  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
19  ***************************************************************************/
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include "target.h"
26 #include "arm_disassembler.h"
27 #include <helper/log.h>
28 
29 #if HAVE_CAPSTONE
30 #include <capstone/capstone.h>
31 #endif
32 
33 /*
34  * This disassembler supports two main functions for OpenOCD:
35  *
36  *  - Various "disassemble" commands.  OpenOCD can serve as a
37  *    machine-language debugger, without help from GDB.
38  *
39  *  - Single stepping.  Not all ARM cores support hardware single
40  *    stepping.  To work without that support, the debugger must
41  *    be able to decode instructions to find out where to put a
42  *    "next instruction" breakpoint.
43  *
44  * In addition, interpretation of ETM trace data needs some of the
45  * decoding mechanisms.
46  *
47  * At this writing (September 2009) neither function is complete.
48  *
49  *  - ARM decoding
50  *     * Old-style syntax (not UAL) is generally used
51  *     * VFP instructions are not understood (ARMv5 and later)
52  *       except as coprocessor 10/11 operations
53  *     * Most ARM instructions through ARMv6 are decoded, but some
54  *       of the post-ARMv4 opcodes may not be handled yet
55  *		CPS, SDIV, UDIV, LDREX*, STREX*, QASX, ...
56  *     * NEON instructions are not understood (ARMv7-A)
57  *
58  *  - Thumb/Thumb2 decoding
59  *     * UAL syntax should be consistently used
60  *     * Any Thumb2 instructions used in Cortex-M3 (ARMv7-M) should
61  *       be handled properly.  Accordingly, so should the subset
62  *       used in Cortex-M0/M1; and "original" 16-bit Thumb from
63  *       ARMv4T and ARMv5T.
64  *     * Conditional effects of Thumb2 "IT" (if-then) instructions
65  *       are not handled:  the affected instructions are not shown
66  *       with their now-conditional suffixes.
67  *     * Some ARMv6 and ARMv7-M Thumb2 instructions may not be
68  *       handled (minimally for coprocessor access).
69  *     * SIMD instructions, and some other Thumb2 instructions
70  *       from ARMv7-A, are not understood.
71  *
72  *  - ThumbEE decoding
73  *     * As a Thumb2 variant, the Thumb2 comments (above) apply.
74  *     * Opcodes changed by ThumbEE mode are not handled; these
75  *       instructions wrongly decode as LDM and STM.
76  *
77  *  - Jazelle decoding ...  no support whatsoever for Jazelle mode
78  *    or decoding.  ARM encourages use of the more generic ThumbEE
79  *    mode, instead of Jazelle mode, in current chips.
80  *
81  *  - Single-step/emulation ... spotty support, which is only weakly
82  *    tested.  Thumb2 is not supported.  (Arguably a full simulator
83  *    is not needed to support just single stepping.  Recognizing
84  *    branch vs non-branch instructions suffices, except when the
85  *    instruction faults and triggers a synchronous exception which
86  *    can be intercepted using other means.)
87  *
88  * ARM DDI 0406B "ARM Architecture Reference Manual, ARM v7-A and
89  * ARM v7-R edition" gives the most complete coverage of the various
90  * generations of ARM instructions.  At this writing it is publicly
91  * accessible to anyone willing to create an account at the ARM
92  * web site; see http://www.arm.com/documentation/ for information.
93  *
94  * ARM DDI 0403C "ARMv7-M Architecture Reference Manual" provides
95  * more details relevant to the Thumb2-only processors (such as
96  * the Cortex-M implementations).
97  */
98 
99 /* textual representation of the condition field
100  * ALways (default) is omitted (empty string) */
101 static const char *arm_condition_strings[] = {
102 	"EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", "LE", "", "NV"
103 };
104 
105 /* make up for C's missing ROR */
ror(uint32_t value,int places)106 static uint32_t ror(uint32_t value, int places)
107 {
108 	return (value >> places) | (value << (32 - places));
109 }
110 
evaluate_unknown(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)111 static int evaluate_unknown(uint32_t opcode,
112 			    uint32_t address, struct arm_instruction *instruction)
113 {
114 	instruction->type = ARM_UNDEFINED_INSTRUCTION;
115 	snprintf(instruction->text, 128,
116 			"0x%8.8" PRIx32 "\t0x%8.8" PRIx32
117 			"\tUNDEFINED INSTRUCTION", address, opcode);
118 	return ERROR_OK;
119 }
120 
evaluate_pld(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)121 static int evaluate_pld(uint32_t opcode,
122 			uint32_t address, struct arm_instruction *instruction)
123 {
124 	/* PLD */
125 	if ((opcode & 0x0d30f000) == 0x0510f000) {
126 		uint8_t Rn;
127 		uint8_t U;
128 		unsigned offset;
129 
130 		instruction->type = ARM_PLD;
131 		Rn = (opcode & 0xf0000) >> 16;
132 		U = (opcode & 0x00800000) >> 23;
133 		if (Rn == 0xf) {
134 			/* literal */
135 			offset = opcode & 0x0fff;
136 			snprintf(instruction->text, 128,
137 				 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD %s%d",
138 				 address, opcode, U ? "" : "-", offset);
139 		} else {
140 			uint8_t I, R;
141 
142 			I = (opcode & 0x02000000) >> 25;
143 			R = (opcode & 0x00400000) >> 22;
144 
145 			if (I) {
146 				/* register PLD{W} [<Rn>,+/-<Rm>{, <shift>}] */
147 				offset = (opcode & 0x0F80) >> 7;
148 				uint8_t Rm;
149 				Rm = opcode & 0xf;
150 
151 				if (offset == 0) {
152 					/* No shift */
153 					snprintf(instruction->text, 128,
154 						 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD%s [r%d, %sr%d]",
155 						 address, opcode, R ? "" : "W", Rn, U ? "" : "-", Rm);
156 
157 				} else {
158 					uint8_t shift;
159 					shift = (opcode & 0x60) >> 5;
160 
161 					if (shift == 0x0) {
162 						/* LSL */
163 						snprintf(instruction->text, 128,
164 							 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD%s [r%d, %sr%d, LSL #0x%x)",
165 							 address, opcode, R ? "" : "W", Rn, U ? "" : "-", Rm, offset);
166 					} else if (shift == 0x1) {
167 						/* LSR */
168 						snprintf(instruction->text, 128,
169 							 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD%s [r%d, %sr%d, LSR #0x%x)",
170 							 address, opcode, R ? "" : "W", Rn, U ? "" : "-", Rm, offset);
171 					} else if (shift == 0x2) {
172 						/* ASR */
173 						snprintf(instruction->text, 128,
174 							 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD%s [r%d, %sr%d, ASR #0x%x)",
175 							 address, opcode, R ? "" : "W", Rn, U ? "" : "-", Rm, offset);
176 					} else if (shift == 0x3) {
177 						/* ROR */
178 						snprintf(instruction->text, 128,
179 							 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD%s [r%d, %sr%d, ROR #0x%x)",
180 							 address, opcode, R ? "" : "W", Rn, U ? "" : "-", Rm, offset);
181 					}
182 				}
183 			} else {
184 				/* immediate PLD{W} [<Rn>, #+/-<imm12>] */
185 				offset = opcode & 0x0fff;
186 				if (offset == 0) {
187 					snprintf(instruction->text, 128,
188 						 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD%s [r%d]",
189 						 address, opcode, R ? "" : "W", Rn);
190 				} else {
191 					snprintf(instruction->text, 128,
192 						 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD%s [r%d, #%s%d]",
193 						 address, opcode, R ? "" : "W", Rn, U ? "" : "-", offset);
194 				}
195 			}
196 		}
197 		return ERROR_OK;
198 	}
199 	/* DSB */
200 	if ((opcode & 0x07f000f0) == 0x05700040) {
201 		instruction->type = ARM_DSB;
202 
203 		char *opt;
204 		switch (opcode & 0x0000000f) {
205 		case 0xf:
206 			opt = "SY";
207 			break;
208 		case 0xe:
209 			opt = "ST";
210 			break;
211 		case 0xb:
212 			opt = "ISH";
213 			break;
214 		case 0xa:
215 			opt = "ISHST";
216 			break;
217 		case 0x7:
218 			opt = "NSH";
219 			break;
220 		case 0x6:
221 			opt = "NSHST";
222 			break;
223 		case 0x3:
224 			opt = "OSH";
225 			break;
226 		case 0x2:
227 			opt = "OSHST";
228 			break;
229 		default:
230 			opt = "UNK";
231 		}
232 
233 		snprintf(instruction->text,
234 				128,
235 				"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDSB %s",
236 				address, opcode, opt);
237 
238 		return ERROR_OK;
239 	}
240 	/* ISB */
241 	if ((opcode & 0x07f000f0) == 0x05700060) {
242 		instruction->type = ARM_ISB;
243 
244 		snprintf(instruction->text,
245 				128,
246 				"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tISB %s",
247 				address, opcode,
248 				((opcode & 0x0000000f) == 0xf) ? "SY" : "UNK");
249 
250 		return ERROR_OK;
251 	}
252 	return evaluate_unknown(opcode, address, instruction);
253 }
254 
evaluate_srs(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)255 static int evaluate_srs(uint32_t opcode,
256 			uint32_t address, struct arm_instruction *instruction)
257 {
258 	const char *wback = (opcode & (1 << 21)) ? "!" : "";
259 	const char *mode = "";
260 
261 	switch ((opcode >> 23) & 0x3) {
262 		case 0:
263 			mode = "DA";
264 			break;
265 		case 1:
266 			/* "IA" is default */
267 			break;
268 		case 2:
269 			mode = "DB";
270 			break;
271 		case 3:
272 			mode = "IB";
273 			break;
274 	}
275 
276 	switch (opcode & 0x0e500000) {
277 		case 0x08400000:
278 			snprintf(instruction->text, 128, "0x%8.8" PRIx32
279 				"\t0x%8.8" PRIx32
280 				"\tSRS%s\tSP%s, #%d",
281 				address, opcode,
282 				mode, wback,
283 				(unsigned)(opcode & 0x1f));
284 			break;
285 		case 0x08100000:
286 			snprintf(instruction->text, 128, "0x%8.8" PRIx32
287 				"\t0x%8.8" PRIx32
288 				"\tRFE%s\tr%d%s",
289 				address, opcode,
290 				mode,
291 				(unsigned)((opcode >> 16) & 0xf), wback);
292 			break;
293 		default:
294 			return evaluate_unknown(opcode, address, instruction);
295 	}
296 	return ERROR_OK;
297 }
298 
evaluate_swi(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)299 static int evaluate_swi(uint32_t opcode,
300 			uint32_t address, struct arm_instruction *instruction)
301 {
302 	instruction->type = ARM_SWI;
303 
304 	snprintf(instruction->text, 128,
305 			"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSVC %#6.6" PRIx32,
306 			address, opcode, (opcode & 0xffffff));
307 
308 	return ERROR_OK;
309 }
310 
evaluate_blx_imm(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)311 static int evaluate_blx_imm(uint32_t opcode,
312 			    uint32_t address, struct arm_instruction *instruction)
313 {
314 	int offset;
315 	uint32_t immediate;
316 	uint32_t target_address;
317 
318 	instruction->type = ARM_BLX;
319 	immediate = opcode & 0x00ffffff;
320 
321 	/* sign extend 24-bit immediate */
322 	if (immediate & 0x00800000)
323 		offset = 0xff000000 | immediate;
324 	else
325 		offset = immediate;
326 
327 	/* shift two bits left */
328 	offset <<= 2;
329 
330 	/* odd/event halfword */
331 	if (opcode & 0x01000000)
332 		offset |= 0x2;
333 
334 	target_address = address + 8 + offset;
335 
336 	snprintf(instruction->text,
337 			128,
338 			"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX 0x%8.8" PRIx32 "",
339 			address,
340 			opcode,
341 			target_address);
342 
343 	instruction->info.b_bl_bx_blx.reg_operand = -1;
344 	instruction->info.b_bl_bx_blx.target_address = target_address;
345 
346 	return ERROR_OK;
347 }
348 
evaluate_b_bl(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)349 static int evaluate_b_bl(uint32_t opcode,
350 			 uint32_t address, struct arm_instruction *instruction)
351 {
352 	uint8_t L;
353 	uint32_t immediate;
354 	int offset;
355 	uint32_t target_address;
356 
357 	immediate = opcode & 0x00ffffff;
358 	L = (opcode & 0x01000000) >> 24;
359 
360 	/* sign extend 24-bit immediate */
361 	if (immediate & 0x00800000)
362 		offset = 0xff000000 | immediate;
363 	else
364 		offset = immediate;
365 
366 	/* shift two bits left */
367 	offset <<= 2;
368 
369 	target_address = address + 8 + offset;
370 
371 	if (L)
372 		instruction->type = ARM_BL;
373 	else
374 		instruction->type = ARM_B;
375 
376 	snprintf(instruction->text,
377 			128,
378 			"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tB%s%s 0x%8.8" PRIx32,
379 			address,
380 			opcode,
381 			(L) ? "L" : "",
382 			COND(opcode),
383 			target_address);
384 
385 	instruction->info.b_bl_bx_blx.reg_operand = -1;
386 	instruction->info.b_bl_bx_blx.target_address = target_address;
387 
388 	return ERROR_OK;
389 }
390 
391 /* Coprocessor load/store and double register transfers
392  * both normal and extended instruction space (condition field b1111) */
evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)393 static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode,
394 				      uint32_t address, struct arm_instruction *instruction)
395 {
396 	uint8_t cp_num = (opcode & 0xf00) >> 8;
397 
398 	/* MCRR or MRRC */
399 	if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c500000)) {
400 		uint8_t cp_opcode, Rd, Rn, CRm;
401 		char *mnemonic;
402 
403 		cp_opcode = (opcode & 0xf0) >> 4;
404 		Rd = (opcode & 0xf000) >> 12;
405 		Rn = (opcode & 0xf0000) >> 16;
406 		CRm = (opcode & 0xf);
407 
408 		/* MCRR */
409 		if ((opcode & 0x0ff00000) == 0x0c400000) {
410 			instruction->type = ARM_MCRR;
411 			mnemonic = "MCRR";
412 		} else if ((opcode & 0x0ff00000) == 0x0c500000) {
413 			/* MRRC */
414 			instruction->type = ARM_MRRC;
415 			mnemonic = "MRRC";
416 		} else {
417 			LOG_ERROR("Unknown instruction");
418 			return ERROR_FAIL;
419 		}
420 
421 		snprintf(instruction->text, 128,
422 				"0x%8.8" PRIx32 "\t0x%8.8" PRIx32
423 				"\t%s%s%s p%i, %x, r%i, r%i, c%i",
424 				address, opcode, mnemonic,
425 				((opcode & 0xf0000000) == 0xf0000000)
426 				? "2" : COND(opcode),
427 				COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm);
428 	} else {/* LDC or STC */
429 		uint8_t CRd, Rn, offset;
430 		uint8_t U;
431 		char *mnemonic;
432 		char addressing_mode[32];
433 
434 		CRd = (opcode & 0xf000) >> 12;
435 		Rn = (opcode & 0xf0000) >> 16;
436 		offset = (opcode & 0xff) << 2;
437 
438 		/* load/store */
439 		if (opcode & 0x00100000) {
440 			instruction->type = ARM_LDC;
441 			mnemonic = "LDC";
442 		} else {
443 			instruction->type = ARM_STC;
444 			mnemonic = "STC";
445 		}
446 
447 		U = (opcode & 0x00800000) >> 23;
448 
449 		/* addressing modes */
450 		if ((opcode & 0x01200000) == 0x01000000)/* offset */
451 			snprintf(addressing_mode, 32, "[r%i, #%s%d]",
452 					Rn, U ? "" : "-", offset);
453 		else if ((opcode & 0x01200000) == 0x01200000)	/* pre-indexed */
454 			snprintf(addressing_mode, 32, "[r%i, #%s%d]!",
455 					Rn, U ? "" : "-", offset);
456 		else if ((opcode & 0x01200000) == 0x00200000)	/* post-indexed */
457 			snprintf(addressing_mode, 32, "[r%i], #%s%d",
458 					Rn, U ? "" : "-", offset);
459 		else if ((opcode & 0x01200000) == 0x00000000)	/* unindexed */
460 			snprintf(addressing_mode, 32, "[r%i], {%d}",
461 					Rn, offset >> 2);
462 
463 		snprintf(instruction->text, 128, "0x%8.8" PRIx32
464 				"\t0x%8.8" PRIx32
465 				"\t%s%s%s p%i, c%i, %s",
466 				address, opcode, mnemonic,
467 				((opcode & 0xf0000000) == 0xf0000000)
468 				? "2" : COND(opcode),
469 				(opcode & (1 << 22)) ? "L" : "",
470 				cp_num, CRd, addressing_mode);
471 	}
472 
473 	return ERROR_OK;
474 }
475 
476 /* Coprocessor data processing instructions
477  * Coprocessor register transfer instructions
478  * both normal and extended instruction space (condition field b1111) */
evaluate_cdp_mcr_mrc(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)479 static int evaluate_cdp_mcr_mrc(uint32_t opcode,
480 				uint32_t address, struct arm_instruction *instruction)
481 {
482 	const char *cond;
483 	char *mnemonic;
484 	uint8_t cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2;
485 
486 	cond = ((opcode & 0xf0000000) == 0xf0000000) ? "2" : COND(opcode);
487 	cp_num = (opcode & 0xf00) >> 8;
488 	CRd_Rd = (opcode & 0xf000) >> 12;
489 	CRn = (opcode & 0xf0000) >> 16;
490 	CRm = (opcode & 0xf);
491 	opcode_2 = (opcode & 0xe0) >> 5;
492 
493 	/* CDP or MRC/MCR */
494 	if (opcode & 0x00000010) {	/* bit 4 set -> MRC/MCR */
495 		if (opcode & 0x00100000) {	/* bit 20 set -> MRC */
496 			instruction->type = ARM_MRC;
497 			mnemonic = "MRC";
498 		} else {/* bit 20 not set -> MCR */
499 			instruction->type = ARM_MCR;
500 			mnemonic = "MCR";
501 		}
502 
503 		opcode_1 = (opcode & 0x00e00000) >> 21;
504 
505 		snprintf(instruction->text,
506 				128,
507 				"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, 0x%2.2x, r%i, c%i, c%i, 0x%2.2x",
508 				address,
509 				opcode,
510 				mnemonic,
511 				cond,
512 				cp_num,
513 				opcode_1,
514 				CRd_Rd,
515 				CRn,
516 				CRm,
517 				opcode_2);
518 	} else {/* bit 4 not set -> CDP */
519 		instruction->type = ARM_CDP;
520 		mnemonic = "CDP";
521 
522 		opcode_1 = (opcode & 0x00f00000) >> 20;
523 
524 		snprintf(instruction->text,
525 				128,
526 				"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, 0x%2.2x, c%i, c%i, c%i, 0x%2.2x",
527 				address,
528 				opcode,
529 				mnemonic,
530 				cond,
531 				cp_num,
532 				opcode_1,
533 				CRd_Rd,
534 				CRn,
535 				CRm,
536 				opcode_2);
537 	}
538 
539 	return ERROR_OK;
540 }
541 
542 /* Load/store instructions */
evaluate_load_store(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)543 static int evaluate_load_store(uint32_t opcode,
544 			       uint32_t address, struct arm_instruction *instruction)
545 {
546 	uint8_t I, P, U, B, W, L;
547 	uint8_t Rn, Rd;
548 	char *operation;/* "LDR" or "STR" */
549 	char *suffix;	/* "", "B", "T", "BT" */
550 	char offset[32];
551 
552 	/* examine flags */
553 	I = (opcode & 0x02000000) >> 25;
554 	P = (opcode & 0x01000000) >> 24;
555 	U = (opcode & 0x00800000) >> 23;
556 	B = (opcode & 0x00400000) >> 22;
557 	W = (opcode & 0x00200000) >> 21;
558 	L = (opcode & 0x00100000) >> 20;
559 
560 	/* target register */
561 	Rd = (opcode & 0xf000) >> 12;
562 
563 	/* base register */
564 	Rn = (opcode & 0xf0000) >> 16;
565 
566 	instruction->info.load_store.Rd = Rd;
567 	instruction->info.load_store.Rn = Rn;
568 	instruction->info.load_store.U = U;
569 
570 	/* determine operation */
571 	if (L)
572 		operation = "LDR";
573 	else
574 		operation = "STR";
575 
576 	/* determine instruction type and suffix */
577 	if (B) {
578 		if ((P == 0) && (W == 1)) {
579 			if (L)
580 				instruction->type = ARM_LDRBT;
581 			else
582 				instruction->type = ARM_STRBT;
583 			suffix = "BT";
584 		} else {
585 			if (L)
586 				instruction->type = ARM_LDRB;
587 			else
588 				instruction->type = ARM_STRB;
589 			suffix = "B";
590 		}
591 	} else {
592 		if ((P == 0) && (W == 1)) {
593 			if (L)
594 				instruction->type = ARM_LDRT;
595 			else
596 				instruction->type = ARM_STRT;
597 			suffix = "T";
598 		} else {
599 			if (L)
600 				instruction->type = ARM_LDR;
601 			else
602 				instruction->type = ARM_STR;
603 			suffix = "";
604 		}
605 	}
606 
607 	if (!I) {	/* #+-<offset_12> */
608 		uint32_t offset_12 = (opcode & 0xfff);
609 		if (offset_12)
610 			snprintf(offset, 32, ", #%s0x%" PRIx32 "", (U) ? "" : "-", offset_12);
611 		else
612 			snprintf(offset, 32, "%s", "");
613 
614 		instruction->info.load_store.offset_mode = 0;
615 		instruction->info.load_store.offset.offset = offset_12;
616 	} else {/* either +-<Rm> or +-<Rm>, <shift>, #<shift_imm> */
617 		uint8_t shift_imm, shift;
618 		uint8_t Rm;
619 
620 		shift_imm = (opcode & 0xf80) >> 7;
621 		shift = (opcode & 0x60) >> 5;
622 		Rm = (opcode & 0xf);
623 
624 		/* LSR encodes a shift by 32 bit as 0x0 */
625 		if ((shift == 0x1) && (shift_imm == 0x0))
626 			shift_imm = 0x20;
627 
628 		/* ASR encodes a shift by 32 bit as 0x0 */
629 		if ((shift == 0x2) && (shift_imm == 0x0))
630 			shift_imm = 0x20;
631 
632 		/* ROR by 32 bit is actually a RRX */
633 		if ((shift == 0x3) && (shift_imm == 0x0))
634 			shift = 0x4;
635 
636 		instruction->info.load_store.offset_mode = 1;
637 		instruction->info.load_store.offset.reg.Rm = Rm;
638 		instruction->info.load_store.offset.reg.shift = shift;
639 		instruction->info.load_store.offset.reg.shift_imm = shift_imm;
640 
641 		if ((shift_imm == 0x0) && (shift == 0x0))	/* +-<Rm> */
642 			snprintf(offset, 32, ", %sr%i", (U) ? "" : "-", Rm);
643 		else {	/* +-<Rm>, <Shift>, #<shift_imm> */
644 			switch (shift) {
645 				case 0x0:		/* LSL */
646 					snprintf(offset, 32, ", %sr%i, LSL #0x%x", (U) ? "" : "-", Rm, shift_imm);
647 					break;
648 				case 0x1:		/* LSR */
649 					snprintf(offset, 32, ", %sr%i, LSR #0x%x", (U) ? "" : "-", Rm, shift_imm);
650 					break;
651 				case 0x2:		/* ASR */
652 					snprintf(offset, 32, ", %sr%i, ASR #0x%x", (U) ? "" : "-", Rm, shift_imm);
653 					break;
654 				case 0x3:		/* ROR */
655 					snprintf(offset, 32, ", %sr%i, ROR #0x%x", (U) ? "" : "-", Rm, shift_imm);
656 					break;
657 				case 0x4:		/* RRX */
658 					snprintf(offset, 32, ", %sr%i, RRX", (U) ? "" : "-", Rm);
659 					break;
660 			}
661 		}
662 	}
663 
664 	if (P == 1) {
665 		if (W == 0) {	/* offset */
666 			snprintf(instruction->text,
667 					128,
668 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]",
669 					address,
670 					opcode,
671 					operation,
672 					COND(opcode),
673 					suffix,
674 					Rd,
675 					Rn,
676 					offset);
677 
678 			instruction->info.load_store.index_mode = 0;
679 		} else {/* pre-indexed */
680 			snprintf(instruction->text,
681 					128,
682 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]!",
683 					address,
684 					opcode,
685 					operation,
686 					COND(opcode),
687 					suffix,
688 					Rd,
689 					Rn,
690 					offset);
691 
692 			instruction->info.load_store.index_mode = 1;
693 		}
694 	} else {/* post-indexed */
695 		snprintf(instruction->text,
696 				128,
697 				"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i]%s",
698 				address,
699 				opcode,
700 				operation,
701 				COND(opcode),
702 				suffix,
703 				Rd,
704 				Rn,
705 				offset);
706 
707 		instruction->info.load_store.index_mode = 2;
708 	}
709 
710 	return ERROR_OK;
711 }
712 
evaluate_extend(uint32_t opcode,uint32_t address,char * cp)713 static int evaluate_extend(uint32_t opcode, uint32_t address, char *cp)
714 {
715 	unsigned rm = (opcode >> 0) & 0xf;
716 	unsigned rd = (opcode >> 12) & 0xf;
717 	unsigned rn = (opcode >> 16) & 0xf;
718 	char *type, *rot;
719 
720 	switch ((opcode >> 24) & 0x3) {
721 		case 0:
722 			type = "B16";
723 			break;
724 		case 1:
725 			sprintf(cp, "UNDEFINED");
726 			return ARM_UNDEFINED_INSTRUCTION;
727 		case 2:
728 			type = "B";
729 			break;
730 		default:
731 			type = "H";
732 			break;
733 	}
734 
735 	switch ((opcode >> 10) & 0x3) {
736 		case 0:
737 			rot = "";
738 			break;
739 		case 1:
740 			rot = ", ROR #8";
741 			break;
742 		case 2:
743 			rot = ", ROR #16";
744 			break;
745 		default:
746 			rot = ", ROR #24";
747 			break;
748 	}
749 
750 	if (rn == 0xf) {
751 		sprintf(cp, "%cXT%s%s\tr%d, r%d%s",
752 				(opcode & (1 << 22)) ? 'U' : 'S',
753 				type, COND(opcode),
754 				rd, rm, rot);
755 		return ARM_MOV;
756 	} else {
757 		sprintf(cp, "%cXTA%s%s\tr%d, r%d, r%d%s",
758 				(opcode & (1 << 22)) ? 'U' : 'S',
759 				type, COND(opcode),
760 				rd, rn, rm, rot);
761 		return ARM_ADD;
762 	}
763 }
764 
evaluate_p_add_sub(uint32_t opcode,uint32_t address,char * cp)765 static int evaluate_p_add_sub(uint32_t opcode, uint32_t address, char *cp)
766 {
767 	char *prefix;
768 	char *op;
769 	int type;
770 
771 	switch ((opcode >> 20) & 0x7) {
772 		case 1:
773 			prefix = "S";
774 			break;
775 		case 2:
776 			prefix = "Q";
777 			break;
778 		case 3:
779 			prefix = "SH";
780 			break;
781 		case 5:
782 			prefix = "U";
783 			break;
784 		case 6:
785 			prefix = "UQ";
786 			break;
787 		case 7:
788 			prefix = "UH";
789 			break;
790 		default:
791 			goto undef;
792 	}
793 
794 	switch ((opcode >> 5) & 0x7) {
795 		case 0:
796 			op = "ADD16";
797 			type = ARM_ADD;
798 			break;
799 		case 1:
800 			op = "ADDSUBX";
801 			type = ARM_ADD;
802 			break;
803 		case 2:
804 			op = "SUBADDX";
805 			type = ARM_SUB;
806 			break;
807 		case 3:
808 			op = "SUB16";
809 			type = ARM_SUB;
810 			break;
811 		case 4:
812 			op = "ADD8";
813 			type = ARM_ADD;
814 			break;
815 		case 7:
816 			op = "SUB8";
817 			type = ARM_SUB;
818 			break;
819 		default:
820 			goto undef;
821 	}
822 
823 	sprintf(cp, "%s%s%s\tr%d, r%d, r%d", prefix, op, COND(opcode),
824 			(int) (opcode >> 12) & 0xf,
825 			(int) (opcode >> 16) & 0xf,
826 			(int) (opcode >> 0) & 0xf);
827 	return type;
828 
829 undef:
830 	/* these opcodes might be used someday */
831 	sprintf(cp, "UNDEFINED");
832 	return ARM_UNDEFINED_INSTRUCTION;
833 }
834 
835 /* ARMv6 and later support "media" instructions (includes SIMD) */
evaluate_media(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)836 static int evaluate_media(uint32_t opcode, uint32_t address,
837 			  struct arm_instruction *instruction)
838 {
839 	char *cp = instruction->text;
840 	char *mnemonic = NULL;
841 
842 	sprintf(cp,
843 			"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t",
844 			address, opcode);
845 	cp = strchr(cp, 0);
846 
847 	/* parallel add/subtract */
848 	if ((opcode & 0x01800000) == 0x00000000) {
849 		instruction->type = evaluate_p_add_sub(opcode, address, cp);
850 		return ERROR_OK;
851 	}
852 
853 	/* halfword pack */
854 	if ((opcode & 0x01f00020) == 0x00800000) {
855 		char *type, *shift;
856 		unsigned imm = (unsigned) (opcode >> 7) & 0x1f;
857 
858 		if (opcode & (1 << 6)) {
859 			type = "TB";
860 			shift = "ASR";
861 			if (imm == 0)
862 				imm = 32;
863 		} else {
864 			type = "BT";
865 			shift = "LSL";
866 		}
867 		sprintf(cp, "PKH%s%s\tr%d, r%d, r%d, %s #%d",
868 				type, COND(opcode),
869 				(int) (opcode >> 12) & 0xf,
870 				(int) (opcode >> 16) & 0xf,
871 				(int) (opcode >> 0) & 0xf,
872 				shift, imm);
873 		return ERROR_OK;
874 	}
875 
876 	/* word saturate */
877 	if ((opcode & 0x01a00020) == 0x00a00000) {
878 		char *shift;
879 		unsigned imm = (unsigned) (opcode >> 7) & 0x1f;
880 
881 		if (opcode & (1 << 6)) {
882 			shift = "ASR";
883 			if (imm == 0)
884 				imm = 32;
885 		} else
886 			shift = "LSL";
887 
888 		sprintf(cp, "%cSAT%s\tr%d, #%d, r%d, %s #%d",
889 				(opcode & (1 << 22)) ? 'U' : 'S',
890 				COND(opcode),
891 				(int) (opcode >> 12) & 0xf,
892 				(int) (opcode >> 16) & 0x1f,
893 				(int) (opcode >> 0) & 0xf,
894 				shift, imm);
895 		return ERROR_OK;
896 	}
897 
898 	/* sign extension */
899 	if ((opcode & 0x018000f0) == 0x00800070) {
900 		instruction->type = evaluate_extend(opcode, address, cp);
901 		return ERROR_OK;
902 	}
903 
904 	/* multiplies */
905 	if ((opcode & 0x01f00080) == 0x01000000) {
906 		unsigned rn = (opcode >> 12) & 0xf;
907 
908 		if (rn != 0xf)
909 			sprintf(cp, "SML%cD%s%s\tr%d, r%d, r%d, r%d",
910 					(opcode & (1 << 6)) ? 'S' : 'A',
911 					(opcode & (1 << 5)) ? "X" : "",
912 					COND(opcode),
913 					(int) (opcode >> 16) & 0xf,
914 					(int) (opcode >> 0) & 0xf,
915 					(int) (opcode >> 8) & 0xf,
916 					rn);
917 		else
918 			sprintf(cp, "SMU%cD%s%s\tr%d, r%d, r%d",
919 					(opcode & (1 << 6)) ? 'S' : 'A',
920 					(opcode & (1 << 5)) ? "X" : "",
921 					COND(opcode),
922 					(int) (opcode >> 16) & 0xf,
923 					(int) (opcode >> 0) & 0xf,
924 					(int) (opcode >> 8) & 0xf);
925 		return ERROR_OK;
926 	}
927 	if ((opcode & 0x01f00000) == 0x01400000) {
928 		sprintf(cp, "SML%cLD%s%s\tr%d, r%d, r%d, r%d",
929 				(opcode & (1 << 6)) ? 'S' : 'A',
930 				(opcode & (1 << 5)) ? "X" : "",
931 				COND(opcode),
932 				(int) (opcode >> 12) & 0xf,
933 				(int) (opcode >> 16) & 0xf,
934 				(int) (opcode >> 0) & 0xf,
935 				(int) (opcode >> 8) & 0xf);
936 		return ERROR_OK;
937 	}
938 	if ((opcode & 0x01f00000) == 0x01500000) {
939 		unsigned rn = (opcode >> 12) & 0xf;
940 
941 		switch (opcode & 0xc0) {
942 			case 3:
943 				if (rn == 0xf)
944 					goto undef;
945 			/* FALL THROUGH */
946 			case 0:
947 				break;
948 			default:
949 				goto undef;
950 		}
951 
952 		if (rn != 0xf)
953 			sprintf(cp, "SMML%c%s%s\tr%d, r%d, r%d, r%d",
954 					(opcode & (1 << 6)) ? 'S' : 'A',
955 					(opcode & (1 << 5)) ? "R" : "",
956 					COND(opcode),
957 					(int) (opcode >> 16) & 0xf,
958 					(int) (opcode >> 0) & 0xf,
959 					(int) (opcode >> 8) & 0xf,
960 					rn);
961 		else
962 			sprintf(cp, "SMMUL%s%s\tr%d, r%d, r%d",
963 					(opcode & (1 << 5)) ? "R" : "",
964 					COND(opcode),
965 					(int) (opcode >> 16) & 0xf,
966 					(int) (opcode >> 0) & 0xf,
967 					(int) (opcode >> 8) & 0xf);
968 		return ERROR_OK;
969 	}
970 
971 	/* simple matches against the remaining decode bits */
972 	switch (opcode & 0x01f000f0) {
973 		case 0x00a00030:
974 		case 0x00e00030:
975 			/* parallel halfword saturate */
976 			sprintf(cp, "%cSAT16%s\tr%d, #%d, r%d",
977 				(opcode & (1 << 22)) ? 'U' : 'S',
978 				COND(opcode),
979 				(int) (opcode >> 12) & 0xf,
980 				(int) (opcode >> 16) & 0xf,
981 				(int) (opcode >> 0) & 0xf);
982 			return ERROR_OK;
983 		case 0x00b00030:
984 			mnemonic = "REV";
985 			break;
986 		case 0x00b000b0:
987 			mnemonic = "REV16";
988 			break;
989 		case 0x00f000b0:
990 			mnemonic = "REVSH";
991 			break;
992 		case 0x008000b0:
993 			/* select bytes */
994 			sprintf(cp, "SEL%s\tr%d, r%d, r%d", COND(opcode),
995 				(int) (opcode >> 12) & 0xf,
996 				(int) (opcode >> 16) & 0xf,
997 				(int) (opcode >> 0) & 0xf);
998 			return ERROR_OK;
999 		case 0x01800010:
1000 			/* unsigned sum of absolute differences */
1001 			if (((opcode >> 12) & 0xf) == 0xf)
1002 				sprintf(cp, "USAD8%s\tr%d, r%d, r%d", COND(opcode),
1003 						(int) (opcode >> 16) & 0xf,
1004 						(int) (opcode >> 0) & 0xf,
1005 						(int) (opcode >> 8) & 0xf);
1006 			else
1007 				sprintf(cp, "USADA8%s\tr%d, r%d, r%d, r%d", COND(opcode),
1008 						(int) (opcode >> 16) & 0xf,
1009 						(int) (opcode >> 0) & 0xf,
1010 						(int) (opcode >> 8) & 0xf,
1011 						(int) (opcode >> 12) & 0xf);
1012 			return ERROR_OK;
1013 	}
1014 	if (mnemonic) {
1015 		unsigned rm = (opcode >> 0) & 0xf;
1016 		unsigned rd = (opcode >> 12) & 0xf;
1017 
1018 		sprintf(cp, "%s%s\tr%d, r%d", mnemonic, COND(opcode), rm, rd);
1019 		return ERROR_OK;
1020 	}
1021 
1022 undef:
1023 	/* these opcodes might be used someday */
1024 	sprintf(cp, "UNDEFINED");
1025 	return ERROR_OK;
1026 }
1027 
1028 /* Miscellaneous load/store instructions */
evaluate_misc_load_store(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)1029 static int evaluate_misc_load_store(uint32_t opcode,
1030 				    uint32_t address, struct arm_instruction *instruction)
1031 {
1032 	uint8_t P, U, I, W, L, S, H;
1033 	uint8_t Rn, Rd;
1034 	char *operation;/* "LDR" or "STR" */
1035 	char *suffix;	/* "H", "SB", "SH", "D" */
1036 	char offset[32];
1037 
1038 	/* examine flags */
1039 	P = (opcode & 0x01000000) >> 24;
1040 	U = (opcode & 0x00800000) >> 23;
1041 	I = (opcode & 0x00400000) >> 22;
1042 	W = (opcode & 0x00200000) >> 21;
1043 	L = (opcode & 0x00100000) >> 20;
1044 	S = (opcode & 0x00000040) >> 6;
1045 	H = (opcode & 0x00000020) >> 5;
1046 
1047 	/* target register */
1048 	Rd = (opcode & 0xf000) >> 12;
1049 
1050 	/* base register */
1051 	Rn = (opcode & 0xf0000) >> 16;
1052 
1053 	instruction->info.load_store.Rd = Rd;
1054 	instruction->info.load_store.Rn = Rn;
1055 	instruction->info.load_store.U = U;
1056 
1057 	/* determine instruction type and suffix */
1058 	if (S) {/* signed */
1059 		if (L) {/* load */
1060 			if (H) {
1061 				operation = "LDR";
1062 				instruction->type = ARM_LDRSH;
1063 				suffix = "SH";
1064 			} else {
1065 				operation = "LDR";
1066 				instruction->type = ARM_LDRSB;
1067 				suffix = "SB";
1068 			}
1069 		} else {/* there are no signed stores, so this is used to encode double-register
1070 			 *load/stores */
1071 			suffix = "D";
1072 			if (H) {
1073 				operation = "STR";
1074 				instruction->type = ARM_STRD;
1075 			} else {
1076 				operation = "LDR";
1077 				instruction->type = ARM_LDRD;
1078 			}
1079 		}
1080 	} else {/* unsigned */
1081 		suffix = "H";
1082 		if (L) {/* load */
1083 			operation = "LDR";
1084 			instruction->type = ARM_LDRH;
1085 		} else {/* store */
1086 			operation = "STR";
1087 			instruction->type = ARM_STRH;
1088 		}
1089 	}
1090 
1091 	if (I) {/* Immediate offset/index (#+-<offset_8>)*/
1092 		uint32_t offset_8 = ((opcode & 0xf00) >> 4) | (opcode & 0xf);
1093 		snprintf(offset, 32, "#%s0x%" PRIx32 "", (U) ? "" : "-", offset_8);
1094 
1095 		instruction->info.load_store.offset_mode = 0;
1096 		instruction->info.load_store.offset.offset = offset_8;
1097 	} else {/* Register offset/index (+-<Rm>) */
1098 		uint8_t Rm;
1099 		Rm = (opcode & 0xf);
1100 		snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm);
1101 
1102 		instruction->info.load_store.offset_mode = 1;
1103 		instruction->info.load_store.offset.reg.Rm = Rm;
1104 		instruction->info.load_store.offset.reg.shift = 0x0;
1105 		instruction->info.load_store.offset.reg.shift_imm = 0x0;
1106 	}
1107 
1108 	if (P == 1) {
1109 		if (W == 0) {	/* offset */
1110 			snprintf(instruction->text,
1111 					128,
1112 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]",
1113 					address,
1114 					opcode,
1115 					operation,
1116 					COND(opcode),
1117 					suffix,
1118 					Rd,
1119 					Rn,
1120 					offset);
1121 
1122 			instruction->info.load_store.index_mode = 0;
1123 		} else {/* pre-indexed */
1124 			snprintf(instruction->text,
1125 					128,
1126 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]!",
1127 					address,
1128 					opcode,
1129 					operation,
1130 					COND(opcode),
1131 					suffix,
1132 					Rd,
1133 					Rn,
1134 					offset);
1135 
1136 			instruction->info.load_store.index_mode = 1;
1137 		}
1138 	} else {/* post-indexed */
1139 		snprintf(instruction->text,
1140 				128,
1141 				"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i], %s",
1142 				address,
1143 				opcode,
1144 				operation,
1145 				COND(opcode),
1146 				suffix,
1147 				Rd,
1148 				Rn,
1149 				offset);
1150 
1151 		instruction->info.load_store.index_mode = 2;
1152 	}
1153 
1154 	return ERROR_OK;
1155 }
1156 
1157 /* Load/store multiples instructions */
evaluate_ldm_stm(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)1158 static int evaluate_ldm_stm(uint32_t opcode,
1159 			    uint32_t address, struct arm_instruction *instruction)
1160 {
1161 	uint8_t P, U, S, W, L, Rn;
1162 	uint32_t register_list;
1163 	char *addressing_mode;
1164 	char *mnemonic;
1165 	char reg_list[69];
1166 	char *reg_list_p;
1167 	int i;
1168 	int first_reg = 1;
1169 
1170 	P = (opcode & 0x01000000) >> 24;
1171 	U = (opcode & 0x00800000) >> 23;
1172 	S = (opcode & 0x00400000) >> 22;
1173 	W = (opcode & 0x00200000) >> 21;
1174 	L = (opcode & 0x00100000) >> 20;
1175 	register_list = (opcode & 0xffff);
1176 	Rn = (opcode & 0xf0000) >> 16;
1177 
1178 	instruction->info.load_store_multiple.Rn = Rn;
1179 	instruction->info.load_store_multiple.register_list = register_list;
1180 	instruction->info.load_store_multiple.S = S;
1181 	instruction->info.load_store_multiple.W = W;
1182 
1183 	if (L) {
1184 		instruction->type = ARM_LDM;
1185 		mnemonic = "LDM";
1186 	} else {
1187 		instruction->type = ARM_STM;
1188 		mnemonic = "STM";
1189 	}
1190 
1191 	if (P) {
1192 		if (U) {
1193 			instruction->info.load_store_multiple.addressing_mode = 1;
1194 			addressing_mode = "IB";
1195 		} else {
1196 			instruction->info.load_store_multiple.addressing_mode = 3;
1197 			addressing_mode = "DB";
1198 		}
1199 	} else {
1200 		if (U) {
1201 			instruction->info.load_store_multiple.addressing_mode = 0;
1202 			/* "IA" is the default in UAL syntax */
1203 			addressing_mode = "";
1204 		} else {
1205 			instruction->info.load_store_multiple.addressing_mode = 2;
1206 			addressing_mode = "DA";
1207 		}
1208 	}
1209 
1210 	reg_list_p = reg_list;
1211 	for (i = 0; i <= 15; i++) {
1212 		if ((register_list >> i) & 1) {
1213 			if (first_reg) {
1214 				first_reg = 0;
1215 				reg_list_p += snprintf(reg_list_p,
1216 							(reg_list + 69 - reg_list_p),
1217 							"r%i",
1218 							i);
1219 			} else
1220 				reg_list_p += snprintf(reg_list_p,
1221 							(reg_list + 69 - reg_list_p),
1222 							", r%i",
1223 							i);
1224 		}
1225 	}
1226 
1227 	snprintf(instruction->text, 128,
1228 			"0x%8.8" PRIx32 "\t0x%8.8" PRIx32
1229 			"\t%s%s%s r%i%s, {%s}%s",
1230 			address, opcode,
1231 			mnemonic, addressing_mode, COND(opcode),
1232 			Rn, (W) ? "!" : "", reg_list, (S) ? "^" : "");
1233 
1234 	return ERROR_OK;
1235 }
1236 
1237 /* Multiplies, extra load/stores */
evaluate_mul_and_extra_ld_st(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)1238 static int evaluate_mul_and_extra_ld_st(uint32_t opcode,
1239 					uint32_t address, struct arm_instruction *instruction)
1240 {
1241 	/* Multiply (accumulate) (long) and Swap/swap byte */
1242 	if ((opcode & 0x000000f0) == 0x00000090) {
1243 		/* Multiply (accumulate) */
1244 		if ((opcode & 0x0f800000) == 0x00000000) {
1245 			uint8_t Rm, Rs, Rn, Rd, S;
1246 			Rm = opcode & 0xf;
1247 			Rs = (opcode & 0xf00) >> 8;
1248 			Rn = (opcode & 0xf000) >> 12;
1249 			Rd = (opcode & 0xf0000) >> 16;
1250 			S = (opcode & 0x00100000) >> 20;
1251 
1252 			/* examine A bit (accumulate) */
1253 			if (opcode & 0x00200000) {
1254 				instruction->type = ARM_MLA;
1255 				snprintf(instruction->text,
1256 						128,
1257 						"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMLA%s%s r%i, r%i, r%i, r%i",
1258 						address,
1259 						opcode,
1260 						COND(opcode),
1261 						(S) ? "S" : "",
1262 						Rd,
1263 						Rm,
1264 						Rs,
1265 						Rn);
1266 			} else {
1267 				instruction->type = ARM_MUL;
1268 				snprintf(instruction->text,
1269 						128,
1270 						"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMUL%s%s r%i, r%i, r%i",
1271 						address,
1272 						opcode,
1273 						COND(opcode),
1274 						(S) ? "S" : "",
1275 						Rd,
1276 						Rm,
1277 						Rs);
1278 			}
1279 
1280 			return ERROR_OK;
1281 		}
1282 
1283 		/* Multiply (accumulate) long */
1284 		if ((opcode & 0x0f800000) == 0x00800000) {
1285 			char *mnemonic = NULL;
1286 			uint8_t Rm, Rs, RdHi, RdLow, S;
1287 			Rm = opcode & 0xf;
1288 			Rs = (opcode & 0xf00) >> 8;
1289 			RdHi = (opcode & 0xf000) >> 12;
1290 			RdLow = (opcode & 0xf0000) >> 16;
1291 			S = (opcode & 0x00100000) >> 20;
1292 
1293 			switch ((opcode & 0x00600000) >> 21) {
1294 				case 0x0:
1295 					instruction->type = ARM_UMULL;
1296 					mnemonic = "UMULL";
1297 					break;
1298 				case 0x1:
1299 					instruction->type = ARM_UMLAL;
1300 					mnemonic = "UMLAL";
1301 					break;
1302 				case 0x2:
1303 					instruction->type = ARM_SMULL;
1304 					mnemonic = "SMULL";
1305 					break;
1306 				case 0x3:
1307 					instruction->type = ARM_SMLAL;
1308 					mnemonic = "SMLAL";
1309 					break;
1310 			}
1311 
1312 			snprintf(instruction->text,
1313 					128,
1314 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, r%i, r%i",
1315 					address,
1316 					opcode,
1317 					mnemonic,
1318 					COND(opcode),
1319 					(S) ? "S" : "",
1320 					RdLow,
1321 					RdHi,
1322 					Rm,
1323 					Rs);
1324 
1325 			return ERROR_OK;
1326 		}
1327 
1328 		/* Swap/swap byte */
1329 		if ((opcode & 0x0f800000) == 0x01000000) {
1330 			uint8_t Rm, Rd, Rn;
1331 			Rm = opcode & 0xf;
1332 			Rd = (opcode & 0xf000) >> 12;
1333 			Rn = (opcode & 0xf0000) >> 16;
1334 
1335 			/* examine B flag */
1336 			instruction->type = (opcode & 0x00400000) ? ARM_SWPB : ARM_SWP;
1337 
1338 			snprintf(instruction->text,
1339 					128,
1340 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, [r%i]",
1341 					address,
1342 					opcode,
1343 					(opcode & 0x00400000) ? "SWPB" : "SWP",
1344 					COND(opcode),
1345 					Rd,
1346 					Rm,
1347 					Rn);
1348 			return ERROR_OK;
1349 		}
1350 
1351 	}
1352 
1353 	return evaluate_misc_load_store(opcode, address, instruction);
1354 }
1355 
evaluate_mrs_msr(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)1356 static int evaluate_mrs_msr(uint32_t opcode,
1357 			    uint32_t address, struct arm_instruction *instruction)
1358 {
1359 	int R = (opcode & 0x00400000) >> 22;
1360 	char *PSR = (R) ? "SPSR" : "CPSR";
1361 
1362 	/* Move register to status register (MSR) */
1363 	if (opcode & 0x00200000) {
1364 		instruction->type = ARM_MSR;
1365 
1366 		/* immediate variant */
1367 		if (opcode & 0x02000000) {
1368 			uint8_t immediate = (opcode & 0xff);
1369 			uint8_t rotate = (opcode & 0xf00);
1370 
1371 			snprintf(instruction->text,
1372 					128,
1373 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, 0x%8.8" PRIx32,
1374 					address,
1375 					opcode,
1376 					COND(opcode),
1377 					PSR,
1378 					(opcode & 0x10000) ? "c" : "",
1379 					(opcode & 0x20000) ? "x" : "",
1380 					(opcode & 0x40000) ? "s" : "",
1381 					(opcode & 0x80000) ? "f" : "",
1382 					ror(immediate, (rotate * 2))
1383 					);
1384 		} else {/* register variant */
1385 			uint8_t Rm = opcode & 0xf;
1386 			snprintf(instruction->text,
1387 					128,
1388 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, r%i",
1389 					address,
1390 					opcode,
1391 					COND(opcode),
1392 					PSR,
1393 					(opcode & 0x10000) ? "c" : "",
1394 					(opcode & 0x20000) ? "x" : "",
1395 					(opcode & 0x40000) ? "s" : "",
1396 					(opcode & 0x80000) ? "f" : "",
1397 					Rm
1398 					);
1399 		}
1400 
1401 	} else {/* Move status register to register (MRS) */
1402 		uint8_t Rd;
1403 
1404 		instruction->type = ARM_MRS;
1405 		Rd = (opcode & 0x0000f000) >> 12;
1406 
1407 		snprintf(instruction->text,
1408 				128,
1409 				"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMRS%s r%i, %s",
1410 				address,
1411 				opcode,
1412 				COND(opcode),
1413 				Rd,
1414 				PSR);
1415 	}
1416 
1417 	return ERROR_OK;
1418 }
1419 
1420 /* Miscellaneous instructions */
evaluate_misc_instr(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)1421 static int evaluate_misc_instr(uint32_t opcode,
1422 			       uint32_t address, struct arm_instruction *instruction)
1423 {
1424 	/* MRS/MSR */
1425 	if ((opcode & 0x000000f0) == 0x00000000)
1426 		evaluate_mrs_msr(opcode, address, instruction);
1427 
1428 	/* BX */
1429 	if ((opcode & 0x006000f0) == 0x00200010) {
1430 		uint8_t Rm;
1431 		instruction->type = ARM_BX;
1432 		Rm = opcode & 0xf;
1433 
1434 		snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBX%s r%i",
1435 				address, opcode, COND(opcode), Rm);
1436 
1437 		instruction->info.b_bl_bx_blx.reg_operand = Rm;
1438 		instruction->info.b_bl_bx_blx.target_address = -1;
1439 	}
1440 
1441 	/* BXJ - "Jazelle" support (ARMv5-J) */
1442 	if ((opcode & 0x006000f0) == 0x00200020) {
1443 		uint8_t Rm;
1444 		instruction->type = ARM_BX;
1445 		Rm = opcode & 0xf;
1446 
1447 		snprintf(instruction->text, 128,
1448 				"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBXJ%s r%i",
1449 				address, opcode, COND(opcode), Rm);
1450 
1451 		instruction->info.b_bl_bx_blx.reg_operand = Rm;
1452 		instruction->info.b_bl_bx_blx.target_address = -1;
1453 	}
1454 
1455 	/* CLZ */
1456 	if ((opcode & 0x006000f0) == 0x00600010) {
1457 		uint8_t Rm, Rd;
1458 		instruction->type = ARM_CLZ;
1459 		Rm = opcode & 0xf;
1460 		Rd = (opcode & 0xf000) >> 12;
1461 
1462 		snprintf(instruction->text,
1463 				128,
1464 				"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLZ%s r%i, r%i",
1465 				address,
1466 				opcode,
1467 				COND(opcode),
1468 				Rd,
1469 				Rm);
1470 	}
1471 
1472 	/* BLX(2) */
1473 	if ((opcode & 0x006000f0) == 0x00200030) {
1474 		uint8_t Rm;
1475 		instruction->type = ARM_BLX;
1476 		Rm = opcode & 0xf;
1477 
1478 		snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX%s r%i",
1479 				address, opcode, COND(opcode), Rm);
1480 
1481 		instruction->info.b_bl_bx_blx.reg_operand = Rm;
1482 		instruction->info.b_bl_bx_blx.target_address = -1;
1483 	}
1484 
1485 	/* Enhanced DSP add/subtracts */
1486 	if ((opcode & 0x0000000f0) == 0x00000050) {
1487 		uint8_t Rm, Rd, Rn;
1488 		char *mnemonic = NULL;
1489 		Rm = opcode & 0xf;
1490 		Rd = (opcode & 0xf000) >> 12;
1491 		Rn = (opcode & 0xf0000) >> 16;
1492 
1493 		switch ((opcode & 0x00600000) >> 21) {
1494 			case 0x0:
1495 				instruction->type = ARM_QADD;
1496 				mnemonic = "QADD";
1497 				break;
1498 			case 0x1:
1499 				instruction->type = ARM_QSUB;
1500 				mnemonic = "QSUB";
1501 				break;
1502 			case 0x2:
1503 				instruction->type = ARM_QDADD;
1504 				mnemonic = "QDADD";
1505 				break;
1506 			case 0x3:
1507 				instruction->type = ARM_QDSUB;
1508 				mnemonic = "QDSUB";
1509 				break;
1510 		}
1511 
1512 		snprintf(instruction->text,
1513 				128,
1514 				"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, r%i",
1515 				address,
1516 				opcode,
1517 				mnemonic,
1518 				COND(opcode),
1519 				Rd,
1520 				Rm,
1521 				Rn);
1522 	}
1523 
1524 	/* exception return */
1525 	if ((opcode & 0x0000000f0) == 0x00000060) {
1526 		if (((opcode & 0x600000) >> 21) == 3)
1527 			instruction->type = ARM_ERET;
1528 		snprintf(instruction->text,
1529 				128,
1530 				"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tERET",
1531 				address,
1532 				opcode);
1533 	}
1534 
1535 	/* exception generate instructions */
1536 	if ((opcode & 0x0000000f0) == 0x00000070) {
1537 		uint32_t immediate = 0;
1538 		char *mnemonic = NULL;
1539 
1540 		switch ((opcode & 0x600000) >> 21) {
1541 			case 0x1:
1542 				instruction->type = ARM_BKPT;
1543 				mnemonic = "BRKT";
1544 				immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
1545 				break;
1546 			case 0x2:
1547 				instruction->type = ARM_HVC;
1548 				mnemonic = "HVC";
1549 				immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
1550 				break;
1551 			case 0x3:
1552 				instruction->type = ARM_SMC;
1553 				mnemonic = "SMC";
1554 				immediate = (opcode & 0xf);
1555 				break;
1556 		}
1557 
1558 		snprintf(instruction->text,
1559 				128,
1560 				"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s 0x%4.4" PRIx32 "",
1561 				address,
1562 				opcode,
1563 				mnemonic,
1564 				immediate);
1565 	}
1566 
1567 	/* Enhanced DSP multiplies */
1568 	if ((opcode & 0x000000090) == 0x00000080) {
1569 		int x = (opcode & 0x20) >> 5;
1570 		int y = (opcode & 0x40) >> 6;
1571 
1572 		/* SMLA < x><y> */
1573 		if ((opcode & 0x00600000) == 0x00000000) {
1574 			uint8_t Rd, Rm, Rs, Rn;
1575 			instruction->type = ARM_SMLAxy;
1576 			Rd = (opcode & 0xf0000) >> 16;
1577 			Rm = (opcode & 0xf);
1578 			Rs = (opcode & 0xf00) >> 8;
1579 			Rn = (opcode & 0xf000) >> 12;
1580 
1581 			snprintf(instruction->text,
1582 					128,
1583 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
1584 					address,
1585 					opcode,
1586 					(x) ? "T" : "B",
1587 					(y) ? "T" : "B",
1588 					COND(opcode),
1589 					Rd,
1590 					Rm,
1591 					Rs,
1592 					Rn);
1593 		}
1594 
1595 		/* SMLAL < x><y> */
1596 		if ((opcode & 0x00600000) == 0x00400000) {
1597 			uint8_t RdLow, RdHi, Rm, Rs;
1598 			instruction->type = ARM_SMLAxy;
1599 			RdHi = (opcode & 0xf0000) >> 16;
1600 			RdLow = (opcode & 0xf000) >> 12;
1601 			Rm = (opcode & 0xf);
1602 			Rs = (opcode & 0xf00) >> 8;
1603 
1604 			snprintf(instruction->text,
1605 					128,
1606 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
1607 					address,
1608 					opcode,
1609 					(x) ? "T" : "B",
1610 					(y) ? "T" : "B",
1611 					COND(opcode),
1612 					RdLow,
1613 					RdHi,
1614 					Rm,
1615 					Rs);
1616 		}
1617 
1618 		/* SMLAW < y> */
1619 		if (((opcode & 0x00600000) == 0x00200000) && (x == 0)) {
1620 			uint8_t Rd, Rm, Rs, Rn;
1621 			instruction->type = ARM_SMLAWy;
1622 			Rd = (opcode & 0xf0000) >> 16;
1623 			Rm = (opcode & 0xf);
1624 			Rs = (opcode & 0xf00) >> 8;
1625 			Rn = (opcode & 0xf000) >> 12;
1626 
1627 			snprintf(instruction->text,
1628 					128,
1629 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLAW%s%s r%i, r%i, r%i, r%i",
1630 					address,
1631 					opcode,
1632 					(y) ? "T" : "B",
1633 					COND(opcode),
1634 					Rd,
1635 					Rm,
1636 					Rs,
1637 					Rn);
1638 		}
1639 
1640 		/* SMUL < x><y> */
1641 		if ((opcode & 0x00600000) == 0x00600000) {
1642 			uint8_t Rd, Rm, Rs;
1643 			instruction->type = ARM_SMULxy;
1644 			Rd = (opcode & 0xf0000) >> 16;
1645 			Rm = (opcode & 0xf);
1646 			Rs = (opcode & 0xf00) >> 8;
1647 
1648 			snprintf(instruction->text,
1649 					128,
1650 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s%s r%i, r%i, r%i",
1651 					address,
1652 					opcode,
1653 					(x) ? "T" : "B",
1654 					(y) ? "T" : "B",
1655 					COND(opcode),
1656 					Rd,
1657 					Rm,
1658 					Rs);
1659 		}
1660 
1661 		/* SMULW < y> */
1662 		if (((opcode & 0x00600000) == 0x00200000) && (x == 1)) {
1663 			uint8_t Rd, Rm, Rs;
1664 			instruction->type = ARM_SMULWy;
1665 			Rd = (opcode & 0xf0000) >> 16;
1666 			Rm = (opcode & 0xf);
1667 			Rs = (opcode & 0xf00) >> 8;
1668 
1669 			snprintf(instruction->text,
1670 					128,
1671 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s r%i, r%i, r%i",
1672 					address,
1673 					opcode,
1674 					(y) ? "T" : "B",
1675 					COND(opcode),
1676 					Rd,
1677 					Rm,
1678 					Rs);
1679 		}
1680 	}
1681 
1682 	return ERROR_OK;
1683 }
1684 
evaluate_mov_imm(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)1685 static int evaluate_mov_imm(uint32_t opcode,
1686 			      uint32_t address, struct arm_instruction *instruction)
1687 {
1688 	uint16_t immediate;
1689 	uint8_t Rd;
1690 	bool T;
1691 
1692 	Rd = (opcode & 0xf000) >> 12;
1693 	T = opcode & 0x00400000;
1694 	immediate = (opcode & 0xf0000) >> 4 | (opcode & 0xfff);
1695 
1696 	instruction->type = ARM_MOV;
1697 	instruction->info.data_proc.Rd = Rd;
1698 
1699 	snprintf(instruction->text,
1700 		 128,
1701 		 "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMOV%s%s r%i, #0x%" PRIx16,
1702 		 address,
1703 		 opcode,
1704 		 T ? "T" : "W",
1705 		 COND(opcode),
1706 		 Rd,
1707 		 immediate);
1708 
1709 	return ERROR_OK;
1710 }
1711 
evaluate_data_proc(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)1712 static int evaluate_data_proc(uint32_t opcode,
1713 			      uint32_t address, struct arm_instruction *instruction)
1714 {
1715 	uint8_t I, op, S, Rn, Rd;
1716 	char *mnemonic = NULL;
1717 	char shifter_operand[32];
1718 
1719 	I = (opcode & 0x02000000) >> 25;
1720 	op = (opcode & 0x01e00000) >> 21;
1721 	S = (opcode & 0x00100000) >> 20;
1722 
1723 	Rd = (opcode & 0xf000) >> 12;
1724 	Rn = (opcode & 0xf0000) >> 16;
1725 
1726 	instruction->info.data_proc.Rd = Rd;
1727 	instruction->info.data_proc.Rn = Rn;
1728 	instruction->info.data_proc.S = S;
1729 
1730 	switch (op) {
1731 		case 0x0:
1732 			instruction->type = ARM_AND;
1733 			mnemonic = "AND";
1734 			break;
1735 		case 0x1:
1736 			instruction->type = ARM_EOR;
1737 			mnemonic = "EOR";
1738 			break;
1739 		case 0x2:
1740 			instruction->type = ARM_SUB;
1741 			mnemonic = "SUB";
1742 			break;
1743 		case 0x3:
1744 			instruction->type = ARM_RSB;
1745 			mnemonic = "RSB";
1746 			break;
1747 		case 0x4:
1748 			instruction->type = ARM_ADD;
1749 			mnemonic = "ADD";
1750 			break;
1751 		case 0x5:
1752 			instruction->type = ARM_ADC;
1753 			mnemonic = "ADC";
1754 			break;
1755 		case 0x6:
1756 			instruction->type = ARM_SBC;
1757 			mnemonic = "SBC";
1758 			break;
1759 		case 0x7:
1760 			instruction->type = ARM_RSC;
1761 			mnemonic = "RSC";
1762 			break;
1763 		case 0x8:
1764 			instruction->type = ARM_TST;
1765 			mnemonic = "TST";
1766 			break;
1767 		case 0x9:
1768 			instruction->type = ARM_TEQ;
1769 			mnemonic = "TEQ";
1770 			break;
1771 		case 0xa:
1772 			instruction->type = ARM_CMP;
1773 			mnemonic = "CMP";
1774 			break;
1775 		case 0xb:
1776 			instruction->type = ARM_CMN;
1777 			mnemonic = "CMN";
1778 			break;
1779 		case 0xc:
1780 			instruction->type = ARM_ORR;
1781 			mnemonic = "ORR";
1782 			break;
1783 		case 0xd:
1784 			instruction->type = ARM_MOV;
1785 			mnemonic = "MOV";
1786 			break;
1787 		case 0xe:
1788 			instruction->type = ARM_BIC;
1789 			mnemonic = "BIC";
1790 			break;
1791 		case 0xf:
1792 			instruction->type = ARM_MVN;
1793 			mnemonic = "MVN";
1794 			break;
1795 	}
1796 
1797 	if (I) {/* immediate shifter operand (#<immediate>)*/
1798 		uint8_t immed_8 = opcode & 0xff;
1799 		uint8_t rotate_imm = (opcode & 0xf00) >> 8;
1800 		uint32_t immediate;
1801 
1802 		immediate = ror(immed_8, rotate_imm * 2);
1803 
1804 		snprintf(shifter_operand, 32, "#0x%" PRIx32 "", immediate);
1805 
1806 		instruction->info.data_proc.variant = 0;
1807 		instruction->info.data_proc.shifter_operand.immediate.immediate = immediate;
1808 	} else {/* register-based shifter operand */
1809 		uint8_t shift, Rm;
1810 		shift = (opcode & 0x60) >> 5;
1811 		Rm = (opcode & 0xf);
1812 
1813 		if ((opcode & 0x10) != 0x10) {	/* Immediate shifts ("<Rm>" or "<Rm>, <shift>
1814 						 *#<shift_immediate>") */
1815 			uint8_t shift_imm;
1816 			shift_imm = (opcode & 0xf80) >> 7;
1817 
1818 			instruction->info.data_proc.variant = 1;
1819 			instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
1820 			instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm =
1821 				shift_imm;
1822 			instruction->info.data_proc.shifter_operand.immediate_shift.shift = shift;
1823 
1824 			/* LSR encodes a shift by 32 bit as 0x0 */
1825 			if ((shift == 0x1) && (shift_imm == 0x0))
1826 				shift_imm = 0x20;
1827 
1828 			/* ASR encodes a shift by 32 bit as 0x0 */
1829 			if ((shift == 0x2) && (shift_imm == 0x0))
1830 				shift_imm = 0x20;
1831 
1832 			/* ROR by 32 bit is actually a RRX */
1833 			if ((shift == 0x3) && (shift_imm == 0x0))
1834 				shift = 0x4;
1835 
1836 			if ((shift_imm == 0x0) && (shift == 0x0))
1837 				snprintf(shifter_operand, 32, "r%i", Rm);
1838 			else {
1839 				if (shift == 0x0)	/* LSL */
1840 					snprintf(shifter_operand,
1841 							32,
1842 							"r%i, LSL #0x%x",
1843 							Rm,
1844 							shift_imm);
1845 				else if (shift == 0x1)	/* LSR */
1846 					snprintf(shifter_operand,
1847 							32,
1848 							"r%i, LSR #0x%x",
1849 							Rm,
1850 							shift_imm);
1851 				else if (shift == 0x2)	/* ASR */
1852 					snprintf(shifter_operand,
1853 							32,
1854 							"r%i, ASR #0x%x",
1855 							Rm,
1856 							shift_imm);
1857 				else if (shift == 0x3)	/* ROR */
1858 					snprintf(shifter_operand,
1859 							32,
1860 							"r%i, ROR #0x%x",
1861 							Rm,
1862 							shift_imm);
1863 				else if (shift == 0x4)	/* RRX */
1864 					snprintf(shifter_operand, 32, "r%i, RRX", Rm);
1865 			}
1866 		} else {/* Register shifts ("<Rm>, <shift> <Rs>") */
1867 			uint8_t Rs = (opcode & 0xf00) >> 8;
1868 
1869 			instruction->info.data_proc.variant = 2;
1870 			instruction->info.data_proc.shifter_operand.register_shift.Rm = Rm;
1871 			instruction->info.data_proc.shifter_operand.register_shift.Rs = Rs;
1872 			instruction->info.data_proc.shifter_operand.register_shift.shift = shift;
1873 
1874 			if (shift == 0x0)	/* LSL */
1875 				snprintf(shifter_operand, 32, "r%i, LSL r%i", Rm, Rs);
1876 			else if (shift == 0x1)	/* LSR */
1877 				snprintf(shifter_operand, 32, "r%i, LSR r%i", Rm, Rs);
1878 			else if (shift == 0x2)	/* ASR */
1879 				snprintf(shifter_operand, 32, "r%i, ASR r%i", Rm, Rs);
1880 			else if (shift == 0x3)	/* ROR */
1881 				snprintf(shifter_operand, 32, "r%i, ROR r%i", Rm, Rs);
1882 		}
1883 	}
1884 
1885 	if ((op < 0x8) || (op == 0xc) || (op == 0xe)) {	/* <opcode3>{<cond>}{S} <Rd>, <Rn>,
1886 							 *<shifter_operand> */
1887 		snprintf(instruction->text,
1888 				128,
1889 				"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, %s",
1890 				address,
1891 				opcode,
1892 				mnemonic,
1893 				COND(opcode),
1894 				(S) ? "S" : "",
1895 				Rd,
1896 				Rn,
1897 				shifter_operand);
1898 	} else if ((op == 0xd) || (op == 0xf)) {	/* <opcode1>{<cond>}{S} <Rd>,
1899 							 *<shifter_operand> */
1900 		if (opcode == 0xe1a00000)	/* print MOV r0,r0 as NOP */
1901 			snprintf(instruction->text,
1902 					128,
1903 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tNOP",
1904 					address,
1905 					opcode);
1906 		else
1907 			snprintf(instruction->text,
1908 					128,
1909 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, %s",
1910 					address,
1911 					opcode,
1912 					mnemonic,
1913 					COND(opcode),
1914 					(S) ? "S" : "",
1915 					Rd,
1916 					shifter_operand);
1917 	} else {/* <opcode2>{<cond>} <Rn>, <shifter_operand> */
1918 		snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, %s",
1919 				address, opcode, mnemonic, COND(opcode),
1920 				Rn, shifter_operand);
1921 	}
1922 
1923 	return ERROR_OK;
1924 }
1925 
arm_evaluate_opcode(uint32_t opcode,uint32_t address,struct arm_instruction * instruction)1926 int arm_evaluate_opcode(uint32_t opcode, uint32_t address,
1927 			struct arm_instruction *instruction)
1928 {
1929 	/* clear fields, to avoid confusion */
1930 	memset(instruction, 0, sizeof(struct arm_instruction));
1931 	instruction->opcode = opcode;
1932 	instruction->instruction_size = 4;
1933 
1934 	/* catch opcodes with condition field [31:28] = b1111 */
1935 	if ((opcode & 0xf0000000) == 0xf0000000) {
1936 		/* Undefined instruction (or ARMv5E cache preload PLD) */
1937 		if ((opcode & 0x08000000) == 0x00000000)
1938 			return evaluate_pld(opcode, address, instruction);
1939 
1940 		/* Undefined instruction (or ARMv6+ SRS/RFE) */
1941 		if ((opcode & 0x0e000000) == 0x08000000)
1942 			return evaluate_srs(opcode, address, instruction);
1943 
1944 		/* Branch and branch with link and change to Thumb */
1945 		if ((opcode & 0x0e000000) == 0x0a000000)
1946 			return evaluate_blx_imm(opcode, address, instruction);
1947 
1948 		/* Extended coprocessor opcode space (ARMv5 and higher)
1949 		 * Coprocessor load/store and double register transfers */
1950 		if ((opcode & 0x0e000000) == 0x0c000000)
1951 			return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
1952 
1953 		/* Coprocessor data processing */
1954 		if ((opcode & 0x0f000100) == 0x0c000000)
1955 			return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1956 
1957 		/* Coprocessor register transfers */
1958 		if ((opcode & 0x0f000010) == 0x0c000010)
1959 			return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1960 
1961 		/* Undefined instruction */
1962 		if ((opcode & 0x0f000000) == 0x0f000000) {
1963 			instruction->type = ARM_UNDEFINED_INSTRUCTION;
1964 			snprintf(instruction->text,
1965 					128,
1966 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION",
1967 					address,
1968 					opcode);
1969 			return ERROR_OK;
1970 		}
1971 	}
1972 
1973 	/* catch opcodes with [27:25] = b000 */
1974 	if ((opcode & 0x0e000000) == 0x00000000) {
1975 		/* Multiplies, extra load/stores */
1976 		if ((opcode & 0x00000090) == 0x00000090)
1977 			return evaluate_mul_and_extra_ld_st(opcode, address, instruction);
1978 
1979 		/* Miscellaneous instructions */
1980 		if ((opcode & 0x0f900000) == 0x01000000)
1981 			return evaluate_misc_instr(opcode, address, instruction);
1982 
1983 		return evaluate_data_proc(opcode, address, instruction);
1984 	}
1985 
1986 	/* catch opcodes with [27:25] = b001 */
1987 	if ((opcode & 0x0e000000) == 0x02000000) {
1988 		/* 16-bit immediate load */
1989 		if ((opcode & 0x0fb00000) == 0x03000000)
1990 			return evaluate_mov_imm(opcode, address, instruction);
1991 
1992 		/* Move immediate to status register */
1993 		if ((opcode & 0x0fb00000) == 0x03200000)
1994 			return evaluate_mrs_msr(opcode, address, instruction);
1995 
1996 		return evaluate_data_proc(opcode, address, instruction);
1997 
1998 	}
1999 
2000 	/* catch opcodes with [27:25] = b010 */
2001 	if ((opcode & 0x0e000000) == 0x04000000) {
2002 		/* Load/store immediate offset */
2003 		return evaluate_load_store(opcode, address, instruction);
2004 	}
2005 
2006 	/* catch opcodes with [27:25] = b011 */
2007 	if ((opcode & 0x0e000000) == 0x06000000) {
2008 		/* Load/store register offset */
2009 		if ((opcode & 0x00000010) == 0x00000000)
2010 			return evaluate_load_store(opcode, address, instruction);
2011 
2012 		/* Architecturally Undefined instruction
2013 		 * ... don't expect these to ever be used
2014 		 */
2015 		if ((opcode & 0x07f000f0) == 0x07f000f0) {
2016 			instruction->type = ARM_UNDEFINED_INSTRUCTION;
2017 			snprintf(instruction->text, 128,
2018 					"0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEF",
2019 					address, opcode);
2020 			return ERROR_OK;
2021 		}
2022 
2023 		/* "media" instructions */
2024 		return evaluate_media(opcode, address, instruction);
2025 	}
2026 
2027 	/* catch opcodes with [27:25] = b100 */
2028 	if ((opcode & 0x0e000000) == 0x08000000) {
2029 		/* Load/store multiple */
2030 		return evaluate_ldm_stm(opcode, address, instruction);
2031 	}
2032 
2033 	/* catch opcodes with [27:25] = b101 */
2034 	if ((opcode & 0x0e000000) == 0x0a000000) {
2035 		/* Branch and branch with link */
2036 		return evaluate_b_bl(opcode, address, instruction);
2037 	}
2038 
2039 	/* catch opcodes with [27:25] = b110 */
2040 	if ((opcode & 0x0e000000) == 0x0c000000) {
2041 		/* Coprocessor load/store and double register transfers */
2042 		return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
2043 	}
2044 
2045 	/* catch opcodes with [27:25] = b111 */
2046 	if ((opcode & 0x0e000000) == 0x0e000000) {
2047 		/* Software interrupt */
2048 		if ((opcode & 0x0f000000) == 0x0f000000)
2049 			return evaluate_swi(opcode, address, instruction);
2050 
2051 		/* Coprocessor data processing */
2052 		if ((opcode & 0x0f000010) == 0x0e000000)
2053 			return evaluate_cdp_mcr_mrc(opcode, address, instruction);
2054 
2055 		/* Coprocessor register transfers */
2056 		if ((opcode & 0x0f000010) == 0x0e000010)
2057 			return evaluate_cdp_mcr_mrc(opcode, address, instruction);
2058 	}
2059 
2060 	LOG_ERROR("ARM: should never reach this point (opcode=%08x)",
2061 			(unsigned) opcode);
2062 	return -1;
2063 }
2064 
evaluate_b_bl_blx_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2065 static int evaluate_b_bl_blx_thumb(uint16_t opcode,
2066 				   uint32_t address, struct arm_instruction *instruction)
2067 {
2068 	uint32_t offset = opcode & 0x7ff;
2069 	uint32_t opc = (opcode >> 11) & 0x3;
2070 	uint32_t target_address;
2071 	char *mnemonic = NULL;
2072 
2073 	/* sign extend 11-bit offset */
2074 	if (((opc == 0) || (opc == 2)) && (offset & 0x00000400))
2075 		offset = 0xfffff800 | offset;
2076 
2077 	target_address = address + 4 + (offset << 1);
2078 
2079 	switch (opc) {
2080 		/* unconditional branch */
2081 		case 0:
2082 			instruction->type = ARM_B;
2083 			mnemonic = "B";
2084 			break;
2085 		/* BLX suffix */
2086 		case 1:
2087 			instruction->type = ARM_BLX;
2088 			mnemonic = "BLX";
2089 			target_address &= 0xfffffffc;
2090 			break;
2091 		/* BL/BLX prefix */
2092 		case 2:
2093 			instruction->type = ARM_UNKNOWN_INSTRUCTION;
2094 			mnemonic = "prefix";
2095 			target_address = offset << 12;
2096 			break;
2097 		/* BL suffix */
2098 		case 3:
2099 			instruction->type = ARM_BL;
2100 			mnemonic = "BL";
2101 			break;
2102 	}
2103 
2104 	/* TODO: deal correctly with dual opcode (prefixed) BL/BLX;
2105 	 * these are effectively 32-bit instructions even in Thumb1.  For
2106 	 * disassembly, it's simplest to always use the Thumb2 decoder.
2107 	 *
2108 	 * But some cores will evidently handle them as two instructions,
2109 	 * where exceptions may occur between the two.  The ETMv3.2+ ID
2110 	 * register has a bit which exposes this behavior.
2111 	 */
2112 
2113 	snprintf(instruction->text, 128,
2114 			"0x%8.8" PRIx32 "  0x%4.4x    \t%s\t%#8.8" PRIx32,
2115 			address, opcode, mnemonic, target_address);
2116 
2117 	instruction->info.b_bl_bx_blx.reg_operand = -1;
2118 	instruction->info.b_bl_bx_blx.target_address = target_address;
2119 
2120 	return ERROR_OK;
2121 }
2122 
evaluate_add_sub_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2123 static int evaluate_add_sub_thumb(uint16_t opcode,
2124 				  uint32_t address, struct arm_instruction *instruction)
2125 {
2126 	uint8_t Rd = (opcode >> 0) & 0x7;
2127 	uint8_t Rn = (opcode >> 3) & 0x7;
2128 	uint8_t Rm_imm = (opcode >> 6) & 0x7;
2129 	uint32_t opc = opcode & (1 << 9);
2130 	uint32_t reg_imm  = opcode & (1 << 10);
2131 	char *mnemonic;
2132 
2133 	if (opc) {
2134 		instruction->type = ARM_SUB;
2135 		mnemonic = "SUBS";
2136 	} else {
2137 		/* REVISIT:  if reg_imm == 0, display as "MOVS" */
2138 		instruction->type = ARM_ADD;
2139 		mnemonic = "ADDS";
2140 	}
2141 
2142 	instruction->info.data_proc.Rd = Rd;
2143 	instruction->info.data_proc.Rn = Rn;
2144 	instruction->info.data_proc.S = 1;
2145 
2146 	if (reg_imm) {
2147 		instruction->info.data_proc.variant = 0;/*immediate*/
2148 		instruction->info.data_proc.shifter_operand.immediate.immediate = Rm_imm;
2149 		snprintf(instruction->text, 128,
2150 				"0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, r%i, #%d",
2151 				address, opcode, mnemonic, Rd, Rn, Rm_imm);
2152 	} else {
2153 		instruction->info.data_proc.variant = 1;/*immediate shift*/
2154 		instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm_imm;
2155 		snprintf(instruction->text, 128,
2156 				"0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, r%i, r%i",
2157 				address, opcode, mnemonic, Rd, Rn, Rm_imm);
2158 	}
2159 
2160 	return ERROR_OK;
2161 }
2162 
evaluate_shift_imm_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2163 static int evaluate_shift_imm_thumb(uint16_t opcode,
2164 				    uint32_t address, struct arm_instruction *instruction)
2165 {
2166 	uint8_t Rd = (opcode >> 0) & 0x7;
2167 	uint8_t Rm = (opcode >> 3) & 0x7;
2168 	uint8_t imm = (opcode >> 6) & 0x1f;
2169 	uint8_t opc = (opcode >> 11) & 0x3;
2170 	char *mnemonic = NULL;
2171 
2172 	switch (opc) {
2173 		case 0:
2174 			instruction->type = ARM_MOV;
2175 			mnemonic = "LSLS";
2176 			instruction->info.data_proc.shifter_operand.immediate_shift.shift = 0;
2177 			break;
2178 		case 1:
2179 			instruction->type = ARM_MOV;
2180 			mnemonic = "LSRS";
2181 			instruction->info.data_proc.shifter_operand.immediate_shift.shift = 1;
2182 			break;
2183 		case 2:
2184 			instruction->type = ARM_MOV;
2185 			mnemonic = "ASRS";
2186 			instruction->info.data_proc.shifter_operand.immediate_shift.shift = 2;
2187 			break;
2188 	}
2189 
2190 	if ((imm == 0) && (opc != 0))
2191 		imm = 32;
2192 
2193 	instruction->info.data_proc.Rd = Rd;
2194 	instruction->info.data_proc.Rn = -1;
2195 	instruction->info.data_proc.S = 1;
2196 
2197 	instruction->info.data_proc.variant = 1;/*immediate_shift*/
2198 	instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
2199 	instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = imm;
2200 
2201 	snprintf(instruction->text, 128,
2202 			"0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, r%i, #%#2.2x",
2203 			address, opcode, mnemonic, Rd, Rm, imm);
2204 
2205 	return ERROR_OK;
2206 }
2207 
evaluate_data_proc_imm_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2208 static int evaluate_data_proc_imm_thumb(uint16_t opcode,
2209 					uint32_t address, struct arm_instruction *instruction)
2210 {
2211 	uint8_t imm = opcode & 0xff;
2212 	uint8_t Rd = (opcode >> 8) & 0x7;
2213 	uint32_t opc = (opcode >> 11) & 0x3;
2214 	char *mnemonic = NULL;
2215 
2216 	instruction->info.data_proc.Rd = Rd;
2217 	instruction->info.data_proc.Rn = Rd;
2218 	instruction->info.data_proc.S = 1;
2219 	instruction->info.data_proc.variant = 0;/*immediate*/
2220 	instruction->info.data_proc.shifter_operand.immediate.immediate = imm;
2221 
2222 	switch (opc) {
2223 		case 0:
2224 			instruction->type = ARM_MOV;
2225 			mnemonic = "MOVS";
2226 			instruction->info.data_proc.Rn = -1;
2227 			break;
2228 		case 1:
2229 			instruction->type = ARM_CMP;
2230 			mnemonic = "CMP";
2231 			instruction->info.data_proc.Rd = -1;
2232 			break;
2233 		case 2:
2234 			instruction->type = ARM_ADD;
2235 			mnemonic = "ADDS";
2236 			break;
2237 		case 3:
2238 			instruction->type = ARM_SUB;
2239 			mnemonic = "SUBS";
2240 			break;
2241 	}
2242 
2243 	snprintf(instruction->text, 128,
2244 			"0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, #%#2.2x",
2245 			address, opcode, mnemonic, Rd, imm);
2246 
2247 	return ERROR_OK;
2248 }
2249 
evaluate_data_proc_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2250 static int evaluate_data_proc_thumb(uint16_t opcode,
2251 				    uint32_t address, struct arm_instruction *instruction)
2252 {
2253 	uint8_t high_reg, op, Rm, Rd, H1, H2;
2254 	char *mnemonic = NULL;
2255 	bool nop = false;
2256 
2257 	high_reg = (opcode & 0x0400) >> 10;
2258 	op = (opcode & 0x03C0) >> 6;
2259 
2260 	Rd = (opcode & 0x0007);
2261 	Rm = (opcode & 0x0038) >> 3;
2262 	H1 = (opcode & 0x0080) >> 7;
2263 	H2 = (opcode & 0x0040) >> 6;
2264 
2265 	instruction->info.data_proc.Rd = Rd;
2266 	instruction->info.data_proc.Rn = Rd;
2267 	instruction->info.data_proc.S = (!high_reg || (instruction->type == ARM_CMP));
2268 	instruction->info.data_proc.variant = 1	/*immediate shift*/;
2269 	instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
2270 
2271 	if (high_reg) {
2272 		Rd |= H1 << 3;
2273 		Rm |= H2 << 3;
2274 		op >>= 2;
2275 
2276 		switch (op) {
2277 			case 0x0:
2278 				instruction->type = ARM_ADD;
2279 				mnemonic = "ADD";
2280 				break;
2281 			case 0x1:
2282 				instruction->type = ARM_CMP;
2283 				mnemonic = "CMP";
2284 				break;
2285 			case 0x2:
2286 				instruction->type = ARM_MOV;
2287 				mnemonic = "MOV";
2288 				if (Rd == Rm)
2289 					nop = true;
2290 				break;
2291 			case 0x3:
2292 				if ((opcode & 0x7) == 0x0) {
2293 					instruction->info.b_bl_bx_blx.reg_operand = Rm;
2294 					if (H1) {
2295 						instruction->type = ARM_BLX;
2296 						snprintf(instruction->text, 128,
2297 								"0x%8.8" PRIx32
2298 								"  0x%4.4x    \tBLX\tr%i",
2299 								address, opcode, Rm);
2300 					} else {
2301 						instruction->type = ARM_BX;
2302 						snprintf(instruction->text, 128,
2303 								"0x%8.8" PRIx32
2304 								"  0x%4.4x    \tBX\tr%i",
2305 								address, opcode, Rm);
2306 					}
2307 				} else {
2308 					instruction->type = ARM_UNDEFINED_INSTRUCTION;
2309 					snprintf(instruction->text, 128,
2310 							"0x%8.8" PRIx32
2311 							"  0x%4.4x    \t"
2312 							"UNDEFINED INSTRUCTION",
2313 							address, opcode);
2314 				}
2315 				return ERROR_OK;
2316 		}
2317 	} else {
2318 		switch (op) {
2319 			case 0x0:
2320 				instruction->type = ARM_AND;
2321 				mnemonic = "ANDS";
2322 				break;
2323 			case 0x1:
2324 				instruction->type = ARM_EOR;
2325 				mnemonic = "EORS";
2326 				break;
2327 			case 0x2:
2328 				instruction->type = ARM_MOV;
2329 				mnemonic = "LSLS";
2330 				instruction->info.data_proc.variant = 2	/*register shift*/;
2331 				instruction->info.data_proc.shifter_operand.register_shift.shift = 0;
2332 				instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2333 				instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2334 				break;
2335 			case 0x3:
2336 				instruction->type = ARM_MOV;
2337 				mnemonic = "LSRS";
2338 				instruction->info.data_proc.variant = 2	/*register shift*/;
2339 				instruction->info.data_proc.shifter_operand.register_shift.shift = 1;
2340 				instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2341 				instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2342 				break;
2343 			case 0x4:
2344 				instruction->type = ARM_MOV;
2345 				mnemonic = "ASRS";
2346 				instruction->info.data_proc.variant = 2	/*register shift*/;
2347 				instruction->info.data_proc.shifter_operand.register_shift.shift = 2;
2348 				instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2349 				instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2350 				break;
2351 			case 0x5:
2352 				instruction->type = ARM_ADC;
2353 				mnemonic = "ADCS";
2354 				break;
2355 			case 0x6:
2356 				instruction->type = ARM_SBC;
2357 				mnemonic = "SBCS";
2358 				break;
2359 			case 0x7:
2360 				instruction->type = ARM_MOV;
2361 				mnemonic = "RORS";
2362 				instruction->info.data_proc.variant = 2	/*register shift*/;
2363 				instruction->info.data_proc.shifter_operand.register_shift.shift = 3;
2364 				instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
2365 				instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
2366 				break;
2367 			case 0x8:
2368 				instruction->type = ARM_TST;
2369 				mnemonic = "TST";
2370 				break;
2371 			case 0x9:
2372 				instruction->type = ARM_RSB;
2373 				mnemonic = "RSBS";
2374 				instruction->info.data_proc.variant = 0	/*immediate*/;
2375 				instruction->info.data_proc.shifter_operand.immediate.immediate = 0;
2376 				instruction->info.data_proc.Rn = Rm;
2377 				break;
2378 			case 0xA:
2379 				instruction->type = ARM_CMP;
2380 				mnemonic = "CMP";
2381 				break;
2382 			case 0xB:
2383 				instruction->type = ARM_CMN;
2384 				mnemonic = "CMN";
2385 				break;
2386 			case 0xC:
2387 				instruction->type = ARM_ORR;
2388 				mnemonic = "ORRS";
2389 				break;
2390 			case 0xD:
2391 				instruction->type = ARM_MUL;
2392 				mnemonic = "MULS";
2393 				break;
2394 			case 0xE:
2395 				instruction->type = ARM_BIC;
2396 				mnemonic = "BICS";
2397 				break;
2398 			case 0xF:
2399 				instruction->type = ARM_MVN;
2400 				mnemonic = "MVNS";
2401 				break;
2402 		}
2403 	}
2404 
2405 	if (nop)
2406 		snprintf(instruction->text, 128,
2407 				"0x%8.8" PRIx32 "  0x%4.4x    \tNOP\t\t\t"
2408 				"; (%s r%i, r%i)",
2409 				address, opcode, mnemonic, Rd, Rm);
2410 	else
2411 		snprintf(instruction->text, 128,
2412 				"0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, r%i",
2413 				address, opcode, mnemonic, Rd, Rm);
2414 
2415 	return ERROR_OK;
2416 }
2417 
2418 /* PC-relative data addressing is word-aligned even with Thumb */
thumb_alignpc4(uint32_t addr)2419 static inline uint32_t thumb_alignpc4(uint32_t addr)
2420 {
2421 	return (addr + 4) & ~3;
2422 }
2423 
evaluate_load_literal_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2424 static int evaluate_load_literal_thumb(uint16_t opcode,
2425 				       uint32_t address, struct arm_instruction *instruction)
2426 {
2427 	uint32_t immediate;
2428 	uint8_t Rd = (opcode >> 8) & 0x7;
2429 
2430 	instruction->type = ARM_LDR;
2431 	immediate = opcode & 0x000000ff;
2432 	immediate *= 4;
2433 
2434 	instruction->info.load_store.Rd = Rd;
2435 	instruction->info.load_store.Rn = 15 /*PC*/;
2436 	instruction->info.load_store.index_mode = 0;	/*offset*/
2437 	instruction->info.load_store.offset_mode = 0;	/*immediate*/
2438 	instruction->info.load_store.offset.offset = immediate;
2439 
2440 	snprintf(instruction->text, 128,
2441 			"0x%8.8" PRIx32 "  0x%4.4x    \t"
2442 			"LDR\tr%i, [pc, #%#" PRIx32 "]\t; %#8.8" PRIx32,
2443 			address, opcode, Rd, immediate,
2444 			thumb_alignpc4(address) + immediate);
2445 
2446 	return ERROR_OK;
2447 }
2448 
evaluate_load_store_reg_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2449 static int evaluate_load_store_reg_thumb(uint16_t opcode,
2450 					 uint32_t address, struct arm_instruction *instruction)
2451 {
2452 	uint8_t Rd = (opcode >> 0) & 0x7;
2453 	uint8_t Rn = (opcode >> 3) & 0x7;
2454 	uint8_t Rm = (opcode >> 6) & 0x7;
2455 	uint8_t opc = (opcode >> 9) & 0x7;
2456 	char *mnemonic = NULL;
2457 
2458 	switch (opc) {
2459 		case 0:
2460 			instruction->type = ARM_STR;
2461 			mnemonic = "STR";
2462 			break;
2463 		case 1:
2464 			instruction->type = ARM_STRH;
2465 			mnemonic = "STRH";
2466 			break;
2467 		case 2:
2468 			instruction->type = ARM_STRB;
2469 			mnemonic = "STRB";
2470 			break;
2471 		case 3:
2472 			instruction->type = ARM_LDRSB;
2473 			mnemonic = "LDRSB";
2474 			break;
2475 		case 4:
2476 			instruction->type = ARM_LDR;
2477 			mnemonic = "LDR";
2478 			break;
2479 		case 5:
2480 			instruction->type = ARM_LDRH;
2481 			mnemonic = "LDRH";
2482 			break;
2483 		case 6:
2484 			instruction->type = ARM_LDRB;
2485 			mnemonic = "LDRB";
2486 			break;
2487 		case 7:
2488 			instruction->type = ARM_LDRSH;
2489 			mnemonic = "LDRSH";
2490 			break;
2491 	}
2492 
2493 	snprintf(instruction->text, 128,
2494 			"0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, [r%i, r%i]",
2495 			address, opcode, mnemonic, Rd, Rn, Rm);
2496 
2497 	instruction->info.load_store.Rd = Rd;
2498 	instruction->info.load_store.Rn = Rn;
2499 	instruction->info.load_store.index_mode = 0;	/*offset*/
2500 	instruction->info.load_store.offset_mode = 1;	/*register*/
2501 	instruction->info.load_store.offset.reg.Rm = Rm;
2502 
2503 	return ERROR_OK;
2504 }
2505 
evaluate_load_store_imm_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2506 static int evaluate_load_store_imm_thumb(uint16_t opcode,
2507 					 uint32_t address, struct arm_instruction *instruction)
2508 {
2509 	uint32_t offset = (opcode >> 6) & 0x1f;
2510 	uint8_t Rd = (opcode >> 0) & 0x7;
2511 	uint8_t Rn = (opcode >> 3) & 0x7;
2512 	uint32_t L = opcode & (1 << 11);
2513 	uint32_t B = opcode & (1 << 12);
2514 	char *mnemonic;
2515 	char suffix = ' ';
2516 	uint32_t shift = 2;
2517 
2518 	if (L) {
2519 		instruction->type = ARM_LDR;
2520 		mnemonic = "LDR";
2521 	} else {
2522 		instruction->type = ARM_STR;
2523 		mnemonic = "STR";
2524 	}
2525 
2526 	if ((opcode&0xF000) == 0x8000) {
2527 		suffix = 'H';
2528 		shift = 1;
2529 	} else if (B) {
2530 		suffix = 'B';
2531 		shift = 0;
2532 	}
2533 
2534 	snprintf(instruction->text, 128,
2535 			"0x%8.8" PRIx32 "  0x%4.4x    \t%s%c\tr%i, [r%i, #%#" PRIx32 "]",
2536 			address, opcode, mnemonic, suffix, Rd, Rn, offset << shift);
2537 
2538 	instruction->info.load_store.Rd = Rd;
2539 	instruction->info.load_store.Rn = Rn;
2540 	instruction->info.load_store.index_mode = 0;	/*offset*/
2541 	instruction->info.load_store.offset_mode = 0;	/*immediate*/
2542 	instruction->info.load_store.offset.offset = offset << shift;
2543 
2544 	return ERROR_OK;
2545 }
2546 
evaluate_load_store_stack_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2547 static int evaluate_load_store_stack_thumb(uint16_t opcode,
2548 					   uint32_t address, struct arm_instruction *instruction)
2549 {
2550 	uint32_t offset = opcode  & 0xff;
2551 	uint8_t Rd = (opcode >> 8) & 0x7;
2552 	uint32_t L = opcode & (1 << 11);
2553 	char *mnemonic;
2554 
2555 	if (L) {
2556 		instruction->type = ARM_LDR;
2557 		mnemonic = "LDR";
2558 	} else {
2559 		instruction->type = ARM_STR;
2560 		mnemonic = "STR";
2561 	}
2562 
2563 	snprintf(instruction->text, 128,
2564 			"0x%8.8" PRIx32 "  0x%4.4x    \t%s\tr%i, [SP, #%#" PRIx32 "]",
2565 			address, opcode, mnemonic, Rd, offset*4);
2566 
2567 	instruction->info.load_store.Rd = Rd;
2568 	instruction->info.load_store.Rn = 13 /*SP*/;
2569 	instruction->info.load_store.index_mode = 0;	/*offset*/
2570 	instruction->info.load_store.offset_mode = 0;	/*immediate*/
2571 	instruction->info.load_store.offset.offset = offset*4;
2572 
2573 	return ERROR_OK;
2574 }
2575 
evaluate_add_sp_pc_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2576 static int evaluate_add_sp_pc_thumb(uint16_t opcode,
2577 				    uint32_t address, struct arm_instruction *instruction)
2578 {
2579 	uint32_t imm = opcode  & 0xff;
2580 	uint8_t Rd = (opcode >> 8) & 0x7;
2581 	uint8_t Rn;
2582 	uint32_t SP = opcode & (1 << 11);
2583 	const char *reg_name;
2584 
2585 	instruction->type = ARM_ADD;
2586 
2587 	if (SP) {
2588 		reg_name = "SP";
2589 		Rn = 13;
2590 	} else {
2591 		reg_name = "PC";
2592 		Rn = 15;
2593 	}
2594 
2595 	snprintf(instruction->text, 128,
2596 			"0x%8.8" PRIx32 "  0x%4.4x  \tADD\tr%i, %s, #%#" PRIx32,
2597 			address, opcode, Rd, reg_name, imm * 4);
2598 
2599 	instruction->info.data_proc.variant = 0	/* immediate */;
2600 	instruction->info.data_proc.Rd = Rd;
2601 	instruction->info.data_proc.Rn = Rn;
2602 	instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
2603 
2604 	return ERROR_OK;
2605 }
2606 
evaluate_adjust_stack_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2607 static int evaluate_adjust_stack_thumb(uint16_t opcode,
2608 				       uint32_t address, struct arm_instruction *instruction)
2609 {
2610 	uint32_t imm = opcode  & 0x7f;
2611 	uint8_t opc = opcode & (1 << 7);
2612 	char *mnemonic;
2613 
2614 
2615 	if (opc) {
2616 		instruction->type = ARM_SUB;
2617 		mnemonic = "SUB";
2618 	} else {
2619 		instruction->type = ARM_ADD;
2620 		mnemonic = "ADD";
2621 	}
2622 
2623 	snprintf(instruction->text, 128,
2624 			"0x%8.8" PRIx32 "  0x%4.4x    \t%s\tSP, #%#" PRIx32,
2625 			address, opcode, mnemonic, imm*4);
2626 
2627 	instruction->info.data_proc.variant = 0	/* immediate */;
2628 	instruction->info.data_proc.Rd = 13 /*SP*/;
2629 	instruction->info.data_proc.Rn = 13 /*SP*/;
2630 	instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
2631 
2632 	return ERROR_OK;
2633 }
2634 
evaluate_breakpoint_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2635 static int evaluate_breakpoint_thumb(uint16_t opcode,
2636 				     uint32_t address, struct arm_instruction *instruction)
2637 {
2638 	uint32_t imm = opcode  & 0xff;
2639 
2640 	instruction->type = ARM_BKPT;
2641 
2642 	snprintf(instruction->text, 128,
2643 			"0x%8.8" PRIx32 "  0x%4.4x  \tBKPT\t%#2.2" PRIx32 "",
2644 			address, opcode, imm);
2645 
2646 	return ERROR_OK;
2647 }
2648 
evaluate_load_store_multiple_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2649 static int evaluate_load_store_multiple_thumb(uint16_t opcode,
2650 					      uint32_t address, struct arm_instruction *instruction)
2651 {
2652 	uint32_t reg_list = opcode  & 0xff;
2653 	uint32_t L = opcode & (1 << 11);
2654 	uint32_t R = opcode & (1 << 8);
2655 	uint8_t Rn = (opcode >> 8) & 7;
2656 	uint8_t addr_mode = 0 /* IA */;
2657 	char reg_names[40];
2658 	char *reg_names_p;
2659 	char *mnemonic;
2660 	char ptr_name[7] = "";
2661 	int i;
2662 
2663 	/* REVISIT:  in ThumbEE mode, there are no LDM or STM instructions.
2664 	 * The STMIA and LDMIA opcodes are used for other instructions.
2665 	 */
2666 
2667 	if ((opcode & 0xf000) == 0xc000) {	/* generic load/store multiple */
2668 		char *wback = "!";
2669 
2670 		if (L) {
2671 			instruction->type = ARM_LDM;
2672 			mnemonic = "LDM";
2673 			if (opcode & (1 << Rn))
2674 				wback = "";
2675 		} else {
2676 			instruction->type = ARM_STM;
2677 			mnemonic = "STM";
2678 		}
2679 		snprintf(ptr_name, sizeof(ptr_name), "r%i%s, ", Rn, wback);
2680 	} else {/* push/pop */
2681 		Rn = 13;/* SP */
2682 		if (L) {
2683 			instruction->type = ARM_LDM;
2684 			mnemonic = "POP";
2685 			if (R)
2686 				reg_list |= (1 << 15) /*PC*/;
2687 		} else {
2688 			instruction->type = ARM_STM;
2689 			mnemonic = "PUSH";
2690 			addr_mode = 3;	/*DB*/
2691 			if (R)
2692 				reg_list |= (1 << 14) /*LR*/;
2693 		}
2694 	}
2695 
2696 	reg_names_p = reg_names;
2697 	for (i = 0; i <= 15; i++) {
2698 		if (reg_list & (1 << i))
2699 			reg_names_p += snprintf(reg_names_p,
2700 						(reg_names + 40 - reg_names_p),
2701 						"r%i, ",
2702 						i);
2703 	}
2704 	if (reg_names_p > reg_names)
2705 		reg_names_p[-2] = '\0';
2706 	else	/* invalid op : no registers */
2707 		reg_names[0] = '\0';
2708 
2709 	snprintf(instruction->text, 128,
2710 			"0x%8.8" PRIx32 "  0x%4.4x  \t%s\t%s{%s}",
2711 			address, opcode, mnemonic, ptr_name, reg_names);
2712 
2713 	instruction->info.load_store_multiple.register_list = reg_list;
2714 	instruction->info.load_store_multiple.Rn = Rn;
2715 	instruction->info.load_store_multiple.addressing_mode = addr_mode;
2716 
2717 	return ERROR_OK;
2718 }
2719 
evaluate_cond_branch_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2720 static int evaluate_cond_branch_thumb(uint16_t opcode,
2721 				      uint32_t address, struct arm_instruction *instruction)
2722 {
2723 	uint32_t offset = opcode  & 0xff;
2724 	uint8_t cond = (opcode >> 8) & 0xf;
2725 	uint32_t target_address;
2726 
2727 	if (cond == 0xf) {
2728 		instruction->type = ARM_SWI;
2729 		snprintf(instruction->text, 128,
2730 				"0x%8.8" PRIx32 "  0x%4.4x    \tSVC\t%#2.2" PRIx32,
2731 				address, opcode, offset);
2732 		return ERROR_OK;
2733 	} else if (cond == 0xe) {
2734 		instruction->type = ARM_UNDEFINED_INSTRUCTION;
2735 		snprintf(instruction->text, 128,
2736 				"0x%8.8" PRIx32 "  0x%4.4x    \tUNDEFINED INSTRUCTION",
2737 				address, opcode);
2738 		return ERROR_OK;
2739 	}
2740 
2741 	/* sign extend 8-bit offset */
2742 	if (offset & 0x00000080)
2743 		offset = 0xffffff00 | offset;
2744 
2745 	target_address = address + 4 + (offset << 1);
2746 
2747 	snprintf(instruction->text, 128,
2748 			"0x%8.8" PRIx32 "  0x%4.4x    \tB%s\t%#8.8" PRIx32,
2749 			address, opcode,
2750 			arm_condition_strings[cond], target_address);
2751 
2752 	instruction->type = ARM_B;
2753 	instruction->info.b_bl_bx_blx.reg_operand = -1;
2754 	instruction->info.b_bl_bx_blx.target_address = target_address;
2755 
2756 	return ERROR_OK;
2757 }
2758 
evaluate_cb_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2759 static int evaluate_cb_thumb(uint16_t opcode, uint32_t address,
2760 			     struct arm_instruction *instruction)
2761 {
2762 	unsigned offset;
2763 
2764 	/* added in Thumb2 */
2765 	offset = (opcode >> 3) & 0x1f;
2766 	offset |= (opcode & 0x0200) >> 4;
2767 
2768 	snprintf(instruction->text, 128,
2769 			"0x%8.8" PRIx32 "  0x%4.4x    \tCB%sZ\tr%d, %#8.8" PRIx32,
2770 			address, opcode,
2771 			(opcode & 0x0800) ? "N" : "",
2772 			opcode & 0x7, address + 4 + (offset << 1));
2773 
2774 	return ERROR_OK;
2775 }
2776 
evaluate_extend_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2777 static int evaluate_extend_thumb(uint16_t opcode, uint32_t address,
2778 				 struct arm_instruction *instruction)
2779 {
2780 	/* added in ARMv6 */
2781 	snprintf(instruction->text, 128,
2782 			"0x%8.8" PRIx32 "  0x%4.4x    \t%cXT%c\tr%d, r%d",
2783 			address, opcode,
2784 			(opcode & 0x0080) ? 'U' : 'S',
2785 			(opcode & 0x0040) ? 'B' : 'H',
2786 			opcode & 0x7, (opcode >> 3) & 0x7);
2787 
2788 	return ERROR_OK;
2789 }
2790 
evaluate_cps_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2791 static int evaluate_cps_thumb(uint16_t opcode, uint32_t address,
2792 			      struct arm_instruction *instruction)
2793 {
2794 	/* added in ARMv6 */
2795 	if ((opcode & 0x0ff0) == 0x0650)
2796 		snprintf(instruction->text, 128,
2797 				"0x%8.8" PRIx32 "  0x%4.4x    \tSETEND %s",
2798 				address, opcode,
2799 				(opcode & 0x80) ? "BE" : "LE");
2800 	else	/* ASSUME (opcode & 0x0fe0) == 0x0660 */
2801 		snprintf(instruction->text, 128,
2802 				"0x%8.8" PRIx32 "  0x%4.4x    \tCPSI%c\t%s%s%s",
2803 				address, opcode,
2804 				(opcode & 0x0010) ? 'D' : 'E',
2805 				(opcode & 0x0004) ? "A" : "",
2806 				(opcode & 0x0002) ? "I" : "",
2807 				(opcode & 0x0001) ? "F" : "");
2808 
2809 	return ERROR_OK;
2810 }
2811 
evaluate_byterev_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2812 static int evaluate_byterev_thumb(uint16_t opcode, uint32_t address,
2813 				  struct arm_instruction *instruction)
2814 {
2815 	char *suffix;
2816 
2817 	/* added in ARMv6 */
2818 	switch ((opcode >> 6) & 3) {
2819 		case 0:
2820 			suffix = "";
2821 			break;
2822 		case 1:
2823 			suffix = "16";
2824 			break;
2825 		default:
2826 			suffix = "SH";
2827 			break;
2828 	}
2829 	snprintf(instruction->text, 128,
2830 			"0x%8.8" PRIx32 "  0x%4.4x    \tREV%s\tr%d, r%d",
2831 			address, opcode, suffix,
2832 			opcode & 0x7, (opcode >> 3) & 0x7);
2833 
2834 	return ERROR_OK;
2835 }
2836 
evaluate_hint_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2837 static int evaluate_hint_thumb(uint16_t opcode, uint32_t address,
2838 			       struct arm_instruction *instruction)
2839 {
2840 	char *hint;
2841 
2842 	switch ((opcode >> 4) & 0x0f) {
2843 		case 0:
2844 			hint = "NOP";
2845 			break;
2846 		case 1:
2847 			hint = "YIELD";
2848 			break;
2849 		case 2:
2850 			hint = "WFE";
2851 			break;
2852 		case 3:
2853 			hint = "WFI";
2854 			break;
2855 		case 4:
2856 			hint = "SEV";
2857 			break;
2858 		default:
2859 			hint = "HINT (UNRECOGNIZED)";
2860 			break;
2861 	}
2862 
2863 	snprintf(instruction->text, 128,
2864 			"0x%8.8" PRIx32 "  0x%4.4x    \t%s",
2865 			address, opcode, hint);
2866 
2867 	return ERROR_OK;
2868 }
2869 
evaluate_ifthen_thumb(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2870 static int evaluate_ifthen_thumb(uint16_t opcode, uint32_t address,
2871 				 struct arm_instruction *instruction)
2872 {
2873 	unsigned cond = (opcode >> 4) & 0x0f;
2874 	char *x = "", *y = "", *z = "";
2875 
2876 	if (opcode & 0x01)
2877 		z = (opcode & 0x02) ? "T" : "E";
2878 	if (opcode & 0x03)
2879 		y = (opcode & 0x04) ? "T" : "E";
2880 	if (opcode & 0x07)
2881 		x = (opcode & 0x08) ? "T" : "E";
2882 
2883 	snprintf(instruction->text, 128,
2884 			"0x%8.8" PRIx32 "  0x%4.4x    \tIT%s%s%s\t%s",
2885 			address, opcode,
2886 			x, y, z, arm_condition_strings[cond]);
2887 
2888 	/* NOTE:  strictly speaking, the next 1-4 instructions should
2889 	 * now be displayed with the relevant conditional suffix...
2890 	 */
2891 
2892 	return ERROR_OK;
2893 }
2894 
thumb_evaluate_opcode(uint16_t opcode,uint32_t address,struct arm_instruction * instruction)2895 int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, struct arm_instruction *instruction)
2896 {
2897 	/* clear fields, to avoid confusion */
2898 	memset(instruction, 0, sizeof(struct arm_instruction));
2899 	instruction->opcode = opcode;
2900 	instruction->instruction_size = 2;
2901 
2902 	if ((opcode & 0xe000) == 0x0000) {
2903 		/* add/subtract register or immediate */
2904 		if ((opcode & 0x1800) == 0x1800)
2905 			return evaluate_add_sub_thumb(opcode, address, instruction);
2906 		/* shift by immediate */
2907 		else
2908 			return evaluate_shift_imm_thumb(opcode, address, instruction);
2909 	}
2910 
2911 	/* Add/subtract/compare/move immediate */
2912 	if ((opcode & 0xe000) == 0x2000)
2913 		return evaluate_data_proc_imm_thumb(opcode, address, instruction);
2914 
2915 	/* Data processing instructions */
2916 	if ((opcode & 0xf800) == 0x4000)
2917 		return evaluate_data_proc_thumb(opcode, address, instruction);
2918 
2919 	/* Load from literal pool */
2920 	if ((opcode & 0xf800) == 0x4800)
2921 		return evaluate_load_literal_thumb(opcode, address, instruction);
2922 
2923 	/* Load/Store register offset */
2924 	if ((opcode & 0xf000) == 0x5000)
2925 		return evaluate_load_store_reg_thumb(opcode, address, instruction);
2926 
2927 	/* Load/Store immediate offset */
2928 	if (((opcode & 0xe000) == 0x6000)
2929 			|| ((opcode & 0xf000) == 0x8000))
2930 		return evaluate_load_store_imm_thumb(opcode, address, instruction);
2931 
2932 	/* Load/Store from/to stack */
2933 	if ((opcode & 0xf000) == 0x9000)
2934 		return evaluate_load_store_stack_thumb(opcode, address, instruction);
2935 
2936 	/* Add to SP/PC */
2937 	if ((opcode & 0xf000) == 0xa000)
2938 		return evaluate_add_sp_pc_thumb(opcode, address, instruction);
2939 
2940 	/* Misc */
2941 	if ((opcode & 0xf000) == 0xb000) {
2942 		switch ((opcode >> 8) & 0x0f) {
2943 			case 0x0:
2944 				return evaluate_adjust_stack_thumb(opcode, address, instruction);
2945 			case 0x1:
2946 			case 0x3:
2947 			case 0x9:
2948 			case 0xb:
2949 				return evaluate_cb_thumb(opcode, address, instruction);
2950 			case 0x2:
2951 				return evaluate_extend_thumb(opcode, address, instruction);
2952 			case 0x4:
2953 			case 0x5:
2954 			case 0xc:
2955 			case 0xd:
2956 				return evaluate_load_store_multiple_thumb(opcode, address,
2957 					instruction);
2958 			case 0x6:
2959 				return evaluate_cps_thumb(opcode, address, instruction);
2960 			case 0xa:
2961 				if ((opcode & 0x00c0) == 0x0080)
2962 					break;
2963 				return evaluate_byterev_thumb(opcode, address, instruction);
2964 			case 0xe:
2965 				return evaluate_breakpoint_thumb(opcode, address, instruction);
2966 			case 0xf:
2967 				if (opcode & 0x000f)
2968 					return evaluate_ifthen_thumb(opcode, address,
2969 							instruction);
2970 				else
2971 					return evaluate_hint_thumb(opcode, address,
2972 							instruction);
2973 		}
2974 
2975 		instruction->type = ARM_UNDEFINED_INSTRUCTION;
2976 		snprintf(instruction->text, 128,
2977 				"0x%8.8" PRIx32 "  0x%4.4x    \tUNDEFINED INSTRUCTION",
2978 				address, opcode);
2979 		return ERROR_OK;
2980 	}
2981 
2982 	/* Load/Store multiple */
2983 	if ((opcode & 0xf000) == 0xc000)
2984 		return evaluate_load_store_multiple_thumb(opcode, address, instruction);
2985 
2986 	/* Conditional branch + SWI */
2987 	if ((opcode & 0xf000) == 0xd000)
2988 		return evaluate_cond_branch_thumb(opcode, address, instruction);
2989 
2990 	if ((opcode & 0xe000) == 0xe000) {
2991 		/* Undefined instructions */
2992 		if ((opcode & 0xf801) == 0xe801) {
2993 			instruction->type = ARM_UNDEFINED_INSTRUCTION;
2994 			snprintf(instruction->text, 128,
2995 					"0x%8.8" PRIx32 "  0x%8.8x\t"
2996 					"UNDEFINED INSTRUCTION",
2997 					address, opcode);
2998 			return ERROR_OK;
2999 		} else	/* Branch to offset */
3000 			return evaluate_b_bl_blx_thumb(opcode, address, instruction);
3001 	}
3002 
3003 	LOG_ERROR("Thumb: should never reach this point (opcode=%04x)", opcode);
3004 	return -1;
3005 }
3006 
arm_access_size(struct arm_instruction * instruction)3007 int arm_access_size(struct arm_instruction *instruction)
3008 {
3009 	if ((instruction->type == ARM_LDRB)
3010 	    || (instruction->type == ARM_LDRBT)
3011 	    || (instruction->type == ARM_LDRSB)
3012 	    || (instruction->type == ARM_STRB)
3013 	    || (instruction->type == ARM_STRBT))
3014 		return 1;
3015 	else if ((instruction->type == ARM_LDRH)
3016 		 || (instruction->type == ARM_LDRSH)
3017 		 || (instruction->type == ARM_STRH))
3018 		return 2;
3019 	else if ((instruction->type == ARM_LDR)
3020 		 || (instruction->type == ARM_LDRT)
3021 		 || (instruction->type == ARM_STR)
3022 		 || (instruction->type == ARM_STRT))
3023 		return 4;
3024 	else if ((instruction->type == ARM_LDRD)
3025 		 || (instruction->type == ARM_STRD))
3026 		return 8;
3027 	else {
3028 		LOG_ERROR("BUG: instruction type %i isn't a load/store instruction",
3029 				instruction->type);
3030 		return 0;
3031 	}
3032 }
3033 
3034 #if HAVE_CAPSTONE
print_opcode(struct command_invocation * cmd,const cs_insn * insn)3035 static void print_opcode(struct command_invocation *cmd, const cs_insn *insn)
3036 {
3037 	uint32_t opcode = 0;
3038 
3039 	memcpy(&opcode, insn->bytes, insn->size);
3040 
3041 	if (insn->size == 4) {
3042 		uint16_t opcode_high = opcode >> 16;
3043 		opcode = opcode & 0xffff;
3044 
3045 		command_print(cmd, "0x%08" PRIx64"  %04x %04x\t%s%s%s",
3046 			insn->address, opcode, opcode_high, insn->mnemonic,
3047 			insn->op_str[0] ? "\t" : "", insn->op_str);
3048 	} else {
3049 		command_print(cmd, "0x%08" PRIx64"  %04x\t%s%s%s",
3050 			insn->address, opcode, insn->mnemonic,
3051 			insn->op_str[0] ? "\t" : "", insn->op_str);
3052 	}
3053 }
3054 
arm_disassemble(struct command_invocation * cmd,struct target * target,target_addr_t address,size_t count,bool thumb_mode)3055 int arm_disassemble(struct command_invocation *cmd, struct target *target,
3056 		target_addr_t address, size_t count, bool thumb_mode)
3057 {
3058 	csh handle;
3059 	int ret;
3060 	cs_insn *insn;
3061 	cs_mode mode;
3062 
3063 	if (!cs_support(CS_ARCH_ARM)) {
3064 		LOG_ERROR("ARM architecture not supported by capstone");
3065 		return ERROR_FAIL;
3066 	}
3067 
3068 	mode = CS_MODE_LITTLE_ENDIAN;
3069 
3070 	if (thumb_mode)
3071 		mode |= CS_MODE_THUMB;
3072 
3073 	ret = cs_open(CS_ARCH_ARM, mode, &handle);
3074 
3075 	if (ret != CS_ERR_OK) {
3076 		LOG_ERROR("cs_open() failed: %s", cs_strerror(ret));
3077 		return ERROR_FAIL;
3078 	}
3079 
3080 	ret = cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);
3081 
3082 	if (ret != CS_ERR_OK) {
3083 		LOG_ERROR("cs_option() failed: %s", cs_strerror(ret));
3084 		cs_close(&handle);
3085 		return ERROR_FAIL;
3086 	}
3087 
3088 	insn = cs_malloc(handle);
3089 
3090 	if (!insn) {
3091 		LOG_ERROR("cs_malloc() failed\n");
3092 		cs_close(&handle);
3093 		return ERROR_FAIL;
3094 	}
3095 
3096 	while (count > 0) {
3097 	    uint8_t buffer[4];
3098 
3099 		ret = target_read_buffer(target, address, sizeof(buffer), buffer);
3100 
3101 		if (ret != ERROR_OK) {
3102 			cs_free(insn, 1);
3103 			cs_close(&handle);
3104 			return ret;
3105 		}
3106 
3107 		size_t size = sizeof(buffer);
3108 		const uint8_t *tmp = buffer;
3109 
3110 		ret = cs_disasm_iter(handle, &tmp, &size, &address, insn);
3111 
3112 		if (!ret) {
3113 			LOG_ERROR("cs_disasm_iter() failed: %s",
3114 				cs_strerror(cs_errno(handle)));
3115 			cs_free(insn, 1);
3116 			cs_close(&handle);
3117 			return ERROR_FAIL;
3118 		}
3119 
3120 		print_opcode(cmd, insn);
3121 		count--;
3122 	}
3123 
3124 	cs_free(insn, 1);
3125 	cs_close(&handle);
3126 
3127 	return ERROR_OK;
3128 }
3129 #endif /* HAVE_CAPSTONE */
3130