Transform 'u64' to 'uint64_t'
[openocd.git] / src / target / arm_disassembler.c
blobe5ca32eb8f49a0a5e34783c8a9a85178c987a035
1 /***************************************************************************
2 * Copyright (C) 2006 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include "arm_disassembler.h"
25 #include "log.h"
28 /* textual represenation of the condition field */
29 /* ALways (default) is ommitted (empty string) */
30 char *arm_condition_strings[] =
32 "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", "LE", "", "NV"
35 /* make up for C's missing ROR */
36 uint32_t ror(uint32_t value, int places)
38 return (value >> places) | (value << (32 - places));
41 int evaluate_pld(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
43 /* PLD */
44 if ((opcode & 0x0d70f0000) == 0x0550f000)
46 instruction->type = ARM_PLD;
48 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tPLD ...TODO...", address, opcode);
50 return ERROR_OK;
52 else
54 instruction->type = ARM_UNDEFINED_INSTRUCTION;
55 return ERROR_OK;
58 LOG_ERROR("should never reach this point");
59 return -1;
62 int evaluate_swi(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
64 instruction->type = ARM_SWI;
66 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSWI 0x%6.6x", address, opcode, (opcode & 0xffffff));
68 return ERROR_OK;
71 int evaluate_blx_imm(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
73 int offset;
74 uint32_t immediate;
75 uint32_t target_address;
77 instruction->type = ARM_BLX;
78 immediate = opcode & 0x00ffffff;
80 /* sign extend 24-bit immediate */
81 if (immediate & 0x00800000)
82 offset = 0xff000000 | immediate;
83 else
84 offset = immediate;
86 /* shift two bits left */
87 offset <<= 2;
89 /* odd/event halfword */
90 if (opcode & 0x01000000)
91 offset |= 0x2;
93 target_address = address + 8 + offset;
95 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tBLX 0x%8.8x", address, opcode, target_address);
97 instruction->info.b_bl_bx_blx.reg_operand = -1;
98 instruction->info.b_bl_bx_blx.target_address = target_address;
100 return ERROR_OK;
103 int evaluate_b_bl(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
105 uint8_t L;
106 uint32_t immediate;
107 int offset;
108 uint32_t target_address;
110 immediate = opcode & 0x00ffffff;
111 L = (opcode & 0x01000000) >> 24;
113 /* sign extend 24-bit immediate */
114 if (immediate & 0x00800000)
115 offset = 0xff000000 | immediate;
116 else
117 offset = immediate;
119 /* shift two bits left */
120 offset <<= 2;
122 target_address = address + 8 + offset;
124 if (L)
125 instruction->type = ARM_BL;
126 else
127 instruction->type = ARM_B;
129 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tB%s%s 0x%8.8x", address, opcode,
130 (L) ? "L" : "", COND(opcode), target_address);
132 instruction->info.b_bl_bx_blx.reg_operand = -1;
133 instruction->info.b_bl_bx_blx.target_address = target_address;
135 return ERROR_OK;
138 /* Coprocessor load/store and double register transfers */
139 /* both normal and extended instruction space (condition field b1111) */
140 int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
142 uint8_t cp_num = (opcode & 0xf00) >> 8;
144 /* MCRR or MRRC */
145 if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c400000))
147 uint8_t cp_opcode, Rd, Rn, CRm;
148 char *mnemonic;
150 cp_opcode = (opcode & 0xf0) >> 4;
151 Rd = (opcode & 0xf000) >> 12;
152 Rn = (opcode & 0xf0000) >> 16;
153 CRm = (opcode & 0xf);
155 /* MCRR */
156 if ((opcode & 0x0ff00000) == 0x0c400000)
158 instruction->type = ARM_MCRR;
159 mnemonic = "MCRR";
162 /* MRRC */
163 if ((opcode & 0x0ff00000) == 0x0c500000)
165 instruction->type = ARM_MRRC;
166 mnemonic = "MRRC";
169 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s p%i, %x, r%i, r%i, c%i",
170 address, opcode, mnemonic, COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm);
172 else /* LDC or STC */
174 uint8_t CRd, Rn, offset;
175 uint8_t U, N;
176 char *mnemonic;
177 char addressing_mode[32];
179 CRd = (opcode & 0xf000) >> 12;
180 Rn = (opcode & 0xf0000) >> 16;
181 offset = (opcode & 0xff);
183 /* load/store */
184 if (opcode & 0x00100000)
186 instruction->type = ARM_LDC;
187 mnemonic = "LDC";
189 else
191 instruction->type = ARM_STC;
192 mnemonic = "STC";
195 U = (opcode & 0x00800000) >> 23;
196 N = (opcode & 0x00400000) >> 22;
198 /* addressing modes */
199 if ((opcode & 0x01200000) == 0x01000000) /* immediate offset */
200 snprintf(addressing_mode, 32, "[r%i, #%s0x%2.2x*4]", Rn, (U) ? "" : "-", offset);
201 else if ((opcode & 0x01200000) == 0x01200000) /* immediate pre-indexed */
202 snprintf(addressing_mode, 32, "[r%i, #%s0x%2.2x*4]!", Rn, (U) ? "" : "-", offset);
203 else if ((opcode & 0x01200000) == 0x00200000) /* immediate post-indexed */
204 snprintf(addressing_mode, 32, "[r%i], #%s0x%2.2x*4", Rn, (U) ? "" : "-", offset);
205 else if ((opcode & 0x01200000) == 0x00000000) /* unindexed */
206 snprintf(addressing_mode, 32, "[r%i], #0x%2.2x", Rn, offset);
208 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s p%i, c%i, %s",
209 address, opcode, mnemonic, ((opcode & 0xf0000000) == 0xf0000000) ? COND(opcode) : "2",
210 (N) ? "L" : "",
211 cp_num, CRd, addressing_mode);
214 return ERROR_OK;
217 /* Coprocessor data processing instructions */
218 /* Coprocessor register transfer instructions */
219 /* both normal and extended instruction space (condition field b1111) */
220 int evaluate_cdp_mcr_mrc(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
222 char* cond;
223 char* mnemonic;
224 uint8_t cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2;
226 cond = ((opcode & 0xf0000000) == 0xf0000000) ? "2" : COND(opcode);
227 cp_num = (opcode & 0xf00) >> 8;
228 CRd_Rd = (opcode & 0xf000) >> 12;
229 CRn = (opcode & 0xf0000) >> 16;
230 CRm = (opcode & 0xf);
231 opcode_2 = (opcode & 0xe0) >> 5;
233 /* CDP or MRC/MCR */
234 if (opcode & 0x00000010) /* bit 4 set -> MRC/MCR */
236 if (opcode & 0x00100000) /* bit 20 set -> MRC */
238 instruction->type = ARM_MRC;
239 mnemonic = "MRC";
241 else /* bit 20 not set -> MCR */
243 instruction->type = ARM_MCR;
244 mnemonic = "MCR";
247 opcode_1 = (opcode & 0x00e00000) >> 21;
249 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s p%i, 0x%2.2x, r%i, c%i, c%i, 0x%2.2x",
250 address, opcode, mnemonic, cond,
251 cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2);
253 else /* bit 4 not set -> CDP */
255 instruction->type = ARM_CDP;
256 mnemonic = "CDP";
258 opcode_1 = (opcode & 0x00f00000) >> 20;
260 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s p%i, 0x%2.2x, c%i, c%i, c%i, 0x%2.2x",
261 address, opcode, mnemonic, cond,
262 cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2);
265 return ERROR_OK;
268 /* Load/store instructions */
269 int evaluate_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
271 uint8_t I, P, U, B, W, L;
272 uint8_t Rn, Rd;
273 char *operation; /* "LDR" or "STR" */
274 char *suffix; /* "", "B", "T", "BT" */
275 char offset[32];
277 /* examine flags */
278 I = (opcode & 0x02000000) >> 25;
279 P = (opcode & 0x01000000) >> 24;
280 U = (opcode & 0x00800000) >> 23;
281 B = (opcode & 0x00400000) >> 22;
282 W = (opcode & 0x00200000) >> 21;
283 L = (opcode & 0x00100000) >> 20;
285 /* target register */
286 Rd = (opcode & 0xf000) >> 12;
288 /* base register */
289 Rn = (opcode & 0xf0000) >> 16;
291 instruction->info.load_store.Rd = Rd;
292 instruction->info.load_store.Rn = Rn;
293 instruction->info.load_store.U = U;
295 /* determine operation */
296 if (L)
297 operation = "LDR";
298 else
299 operation = "STR";
301 /* determine instruction type and suffix */
302 if (B)
304 if ((P == 0) && (W == 1))
306 if (L)
307 instruction->type = ARM_LDRBT;
308 else
309 instruction->type = ARM_STRBT;
310 suffix = "BT";
312 else
314 if (L)
315 instruction->type = ARM_LDRB;
316 else
317 instruction->type = ARM_STRB;
318 suffix = "B";
321 else
323 if ((P == 0) && (W == 1))
325 if (L)
326 instruction->type = ARM_LDRT;
327 else
328 instruction->type = ARM_STRT;
329 suffix = "T";
331 else
333 if (L)
334 instruction->type = ARM_LDR;
335 else
336 instruction->type = ARM_STR;
337 suffix = "";
341 if (!I) /* #+-<offset_12> */
343 uint32_t offset_12 = (opcode & 0xfff);
344 if (offset_12)
345 snprintf(offset, 32, ", #%s0x%x", (U) ? "" : "-", offset_12);
346 else
347 snprintf(offset, 32, "%s", "");
349 instruction->info.load_store.offset_mode = 0;
350 instruction->info.load_store.offset.offset = offset_12;
352 else /* either +-<Rm> or +-<Rm>, <shift>, #<shift_imm> */
354 uint8_t shift_imm, shift;
355 uint8_t Rm;
357 shift_imm = (opcode & 0xf80) >> 7;
358 shift = (opcode & 0x60) >> 5;
359 Rm = (opcode & 0xf);
361 /* LSR encodes a shift by 32 bit as 0x0 */
362 if ((shift == 0x1) && (shift_imm == 0x0))
363 shift_imm = 0x20;
365 /* ASR encodes a shift by 32 bit as 0x0 */
366 if ((shift == 0x2) && (shift_imm == 0x0))
367 shift_imm = 0x20;
369 /* ROR by 32 bit is actually a RRX */
370 if ((shift == 0x3) && (shift_imm == 0x0))
371 shift = 0x4;
373 instruction->info.load_store.offset_mode = 1;
374 instruction->info.load_store.offset.reg.Rm = Rm;
375 instruction->info.load_store.offset.reg.shift = shift;
376 instruction->info.load_store.offset.reg.shift_imm = shift_imm;
378 if ((shift_imm == 0x0) && (shift == 0x0)) /* +-<Rm> */
380 snprintf(offset, 32, ", %sr%i", (U) ? "" : "-", Rm);
382 else /* +-<Rm>, <Shift>, #<shift_imm> */
384 switch (shift)
386 case 0x0: /* LSL */
387 snprintf(offset, 32, ", %sr%i, LSL #0x%x", (U) ? "" : "-", Rm, shift_imm);
388 break;
389 case 0x1: /* LSR */
390 snprintf(offset, 32, ", %sr%i, LSR #0x%x", (U) ? "" : "-", Rm, shift_imm);
391 break;
392 case 0x2: /* ASR */
393 snprintf(offset, 32, ", %sr%i, ASR #0x%x", (U) ? "" : "-", Rm, shift_imm);
394 break;
395 case 0x3: /* ROR */
396 snprintf(offset, 32, ", %sr%i, ROR #0x%x", (U) ? "" : "-", Rm, shift_imm);
397 break;
398 case 0x4: /* RRX */
399 snprintf(offset, 32, ", %sr%i, RRX", (U) ? "" : "-", Rm);
400 break;
405 if (P == 1)
407 if (W == 0) /* offset */
409 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i%s]",
410 address, opcode, operation, COND(opcode), suffix,
411 Rd, Rn, offset);
413 instruction->info.load_store.index_mode = 0;
415 else /* pre-indexed */
417 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i%s]!",
418 address, opcode, operation, COND(opcode), suffix,
419 Rd, Rn, offset);
421 instruction->info.load_store.index_mode = 1;
424 else /* post-indexed */
426 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i]%s",
427 address, opcode, operation, COND(opcode), suffix,
428 Rd, Rn, offset);
430 instruction->info.load_store.index_mode = 2;
433 return ERROR_OK;
436 /* Miscellaneous load/store instructions */
437 int evaluate_misc_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
439 uint8_t P, U, I, W, L, S, H;
440 uint8_t Rn, Rd;
441 char *operation; /* "LDR" or "STR" */
442 char *suffix; /* "H", "SB", "SH", "D" */
443 char offset[32];
445 /* examine flags */
446 P = (opcode & 0x01000000) >> 24;
447 U = (opcode & 0x00800000) >> 23;
448 I = (opcode & 0x00400000) >> 22;
449 W = (opcode & 0x00200000) >> 21;
450 L = (opcode & 0x00100000) >> 20;
451 S = (opcode & 0x00000040) >> 6;
452 H = (opcode & 0x00000020) >> 5;
454 /* target register */
455 Rd = (opcode & 0xf000) >> 12;
457 /* base register */
458 Rn = (opcode & 0xf0000) >> 16;
460 instruction->info.load_store.Rd = Rd;
461 instruction->info.load_store.Rn = Rn;
462 instruction->info.load_store.U = U;
464 /* determine instruction type and suffix */
465 if (S) /* signed */
467 if (L) /* load */
469 if (H)
471 operation = "LDR";
472 instruction->type = ARM_LDRSH;
473 suffix = "SH";
475 else
477 operation = "LDR";
478 instruction->type = ARM_LDRSB;
479 suffix = "SB";
482 else /* there are no signed stores, so this is used to encode double-register load/stores */
484 suffix = "D";
485 if (H)
487 operation = "STR";
488 instruction->type = ARM_STRD;
490 else
492 operation = "LDR";
493 instruction->type = ARM_LDRD;
497 else /* unsigned */
499 suffix = "H";
500 if (L) /* load */
502 operation = "LDR";
503 instruction->type = ARM_LDRH;
505 else /* store */
507 operation = "STR";
508 instruction->type = ARM_STRH;
512 if (I) /* Immediate offset/index (#+-<offset_8>)*/
514 uint32_t offset_8 = ((opcode & 0xf00) >> 4) | (opcode & 0xf);
515 snprintf(offset, 32, "#%s0x%x", (U) ? "" : "-", offset_8);
517 instruction->info.load_store.offset_mode = 0;
518 instruction->info.load_store.offset.offset = offset_8;
520 else /* Register offset/index (+-<Rm>) */
522 uint8_t Rm;
523 Rm = (opcode & 0xf);
524 snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm);
526 instruction->info.load_store.offset_mode = 1;
527 instruction->info.load_store.offset.reg.Rm = Rm;
528 instruction->info.load_store.offset.reg.shift = 0x0;
529 instruction->info.load_store.offset.reg.shift_imm = 0x0;
532 if (P == 1)
534 if (W == 0) /* offset */
536 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i, %s]",
537 address, opcode, operation, COND(opcode), suffix,
538 Rd, Rn, offset);
540 instruction->info.load_store.index_mode = 0;
542 else /* pre-indexed */
544 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i, %s]!",
545 address, opcode, operation, COND(opcode), suffix,
546 Rd, Rn, offset);
548 instruction->info.load_store.index_mode = 1;
551 else /* post-indexed */
553 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i], %s",
554 address, opcode, operation, COND(opcode), suffix,
555 Rd, Rn, offset);
557 instruction->info.load_store.index_mode = 2;
560 return ERROR_OK;
563 /* Load/store multiples instructions */
564 int evaluate_ldm_stm(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
566 uint8_t P, U, S, W, L, Rn;
567 uint32_t register_list;
568 char *addressing_mode;
569 char *mnemonic;
570 char reg_list[69];
571 char *reg_list_p;
572 int i;
573 int first_reg = 1;
575 P = (opcode & 0x01000000) >> 24;
576 U = (opcode & 0x00800000) >> 23;
577 S = (opcode & 0x00400000) >> 22;
578 W = (opcode & 0x00200000) >> 21;
579 L = (opcode & 0x00100000) >> 20;
580 register_list = (opcode & 0xffff);
581 Rn = (opcode & 0xf0000) >> 16;
583 instruction->info.load_store_multiple.Rn = Rn;
584 instruction->info.load_store_multiple.register_list = register_list;
585 instruction->info.load_store_multiple.S = S;
586 instruction->info.load_store_multiple.W = W;
588 if (L)
590 instruction->type = ARM_LDM;
591 mnemonic = "LDM";
593 else
595 instruction->type = ARM_STM;
596 mnemonic = "STM";
599 if (P)
601 if (U)
603 instruction->info.load_store_multiple.addressing_mode = 1;
604 addressing_mode = "IB";
606 else
608 instruction->info.load_store_multiple.addressing_mode = 3;
609 addressing_mode = "DB";
612 else
614 if (U)
616 instruction->info.load_store_multiple.addressing_mode = 0;
617 addressing_mode = "IA";
619 else
621 instruction->info.load_store_multiple.addressing_mode = 2;
622 addressing_mode = "DA";
626 reg_list_p = reg_list;
627 for (i = 0; i <= 15; i++)
629 if ((register_list >> i) & 1)
631 if (first_reg)
633 first_reg = 0;
634 reg_list_p += snprintf(reg_list_p, (reg_list + 69 - reg_list_p), "r%i", i);
636 else
638 reg_list_p += snprintf(reg_list_p, (reg_list + 69 - reg_list_p), ", r%i", i);
643 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i%s, {%s}%s",
644 address, opcode, mnemonic, COND(opcode), addressing_mode,
645 Rn, (W) ? "!" : "", reg_list, (S) ? "^" : "");
647 return ERROR_OK;
650 /* Multiplies, extra load/stores */
651 int evaluate_mul_and_extra_ld_st(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
653 /* Multiply (accumulate) (long) and Swap/swap byte */
654 if ((opcode & 0x000000f0) == 0x00000090)
656 /* Multiply (accumulate) */
657 if ((opcode & 0x0f800000) == 0x00000000)
659 uint8_t Rm, Rs, Rn, Rd, S;
660 Rm = opcode & 0xf;
661 Rs = (opcode & 0xf00) >> 8;
662 Rn = (opcode & 0xf000) >> 12;
663 Rd = (opcode & 0xf0000) >> 16;
664 S = (opcode & 0x00100000) >> 20;
666 /* examine A bit (accumulate) */
667 if (opcode & 0x00200000)
669 instruction->type = ARM_MLA;
670 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tMLA%s%s r%i, r%i, r%i, r%i",
671 address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs, Rn);
673 else
675 instruction->type = ARM_MUL;
676 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tMUL%s%s r%i, r%i, r%i",
677 address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs);
680 return ERROR_OK;
683 /* Multiply (accumulate) long */
684 if ((opcode & 0x0f800000) == 0x00800000)
686 char* mnemonic = NULL;
687 uint8_t Rm, Rs, RdHi, RdLow, S;
688 Rm = opcode & 0xf;
689 Rs = (opcode & 0xf00) >> 8;
690 RdHi = (opcode & 0xf000) >> 12;
691 RdLow = (opcode & 0xf0000) >> 16;
692 S = (opcode & 0x00100000) >> 20;
694 switch ((opcode & 0x00600000) >> 21)
696 case 0x0:
697 instruction->type = ARM_UMULL;
698 mnemonic = "UMULL";
699 break;
700 case 0x1:
701 instruction->type = ARM_UMLAL;
702 mnemonic = "UMLAL";
703 break;
704 case 0x2:
705 instruction->type = ARM_SMULL;
706 mnemonic = "SMULL";
707 break;
708 case 0x3:
709 instruction->type = ARM_SMLAL;
710 mnemonic = "SMLAL";
711 break;
714 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, r%i, r%i, r%i",
715 address, opcode, mnemonic, COND(opcode), (S) ? "S" : "",
716 RdLow, RdHi, Rm, Rs);
718 return ERROR_OK;
721 /* Swap/swap byte */
722 if ((opcode & 0x0f800000) == 0x01000000)
724 uint8_t Rm, Rd, Rn;
725 Rm = opcode & 0xf;
726 Rd = (opcode & 0xf000) >> 12;
727 Rn = (opcode & 0xf0000) >> 16;
729 /* examine B flag */
730 instruction->type = (opcode & 0x00400000) ? ARM_SWPB : ARM_SWP;
732 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s r%i, r%i, [r%i]",
733 address, opcode, (opcode & 0x00400000) ? "SWPB" : "SWP", COND(opcode), Rd, Rm, Rn);
734 return ERROR_OK;
739 return evaluate_misc_load_store(opcode, address, instruction);
742 int evaluate_mrs_msr(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
744 int R = (opcode & 0x00400000) >> 22;
745 char *PSR = (R) ? "SPSR" : "CPSR";
747 /* Move register to status register (MSR) */
748 if (opcode & 0x00200000)
750 instruction->type = ARM_MSR;
752 /* immediate variant */
753 if (opcode & 0x02000000)
755 uint8_t immediate = (opcode & 0xff);
756 uint8_t rotate = (opcode & 0xf00);
758 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tMSR%s %s_%s%s%s%s, 0x%8.8x",
759 address, opcode, COND(opcode), PSR,
760 (opcode & 0x10000) ? "c" : "",
761 (opcode & 0x20000) ? "x" : "",
762 (opcode & 0x40000) ? "s" : "",
763 (opcode & 0x80000) ? "f" : "",
764 ror(immediate, (rotate * 2))
767 else /* register variant */
769 uint8_t Rm = opcode & 0xf;
770 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tMSR%s %s_%s%s%s%s, r%i",
771 address, opcode, COND(opcode), PSR,
772 (opcode & 0x10000) ? "c" : "",
773 (opcode & 0x20000) ? "x" : "",
774 (opcode & 0x40000) ? "s" : "",
775 (opcode & 0x80000) ? "f" : "",
781 else /* Move status register to register (MRS) */
783 uint8_t Rd;
785 instruction->type = ARM_MRS;
786 Rd = (opcode & 0x0000f000) >> 12;
788 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tMRS%s r%i, %s",
789 address, opcode, COND(opcode), Rd, PSR);
792 return ERROR_OK;
795 /* Miscellaneous instructions */
796 int evaluate_misc_instr(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
798 /* MRS/MSR */
799 if ((opcode & 0x000000f0) == 0x00000000)
801 evaluate_mrs_msr(opcode, address, instruction);
804 /* BX */
805 if ((opcode & 0x006000f0) == 0x00200010)
807 uint8_t Rm;
808 instruction->type = ARM_BX;
809 Rm = opcode & 0xf;
811 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tBX%s r%i",
812 address, opcode, COND(opcode), Rm);
814 instruction->info.b_bl_bx_blx.reg_operand = Rm;
815 instruction->info.b_bl_bx_blx.target_address = -1;
818 /* CLZ */
819 if ((opcode & 0x006000f0) == 0x00600010)
821 uint8_t Rm, Rd;
822 instruction->type = ARM_CLZ;
823 Rm = opcode & 0xf;
824 Rd = (opcode & 0xf000) >> 12;
826 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tCLZ%s r%i, r%i",
827 address, opcode, COND(opcode), Rd, Rm);
830 /* BLX(2) */
831 if ((opcode & 0x006000f0) == 0x00200030)
833 uint8_t Rm;
834 instruction->type = ARM_BLX;
835 Rm = opcode & 0xf;
837 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tBLX%s r%i",
838 address, opcode, COND(opcode), Rm);
840 instruction->info.b_bl_bx_blx.reg_operand = Rm;
841 instruction->info.b_bl_bx_blx.target_address = -1;
844 /* Enhanced DSP add/subtracts */
845 if ((opcode & 0x0000000f0) == 0x00000050)
847 uint8_t Rm, Rd, Rn;
848 char *mnemonic = NULL;
849 Rm = opcode & 0xf;
850 Rd = (opcode & 0xf000) >> 12;
851 Rn = (opcode & 0xf0000) >> 16;
853 switch ((opcode & 0x00600000) >> 21)
855 case 0x0:
856 instruction->type = ARM_QADD;
857 mnemonic = "QADD";
858 break;
859 case 0x1:
860 instruction->type = ARM_QSUB;
861 mnemonic = "QSUB";
862 break;
863 case 0x2:
864 instruction->type = ARM_QDADD;
865 mnemonic = "QDADD";
866 break;
867 case 0x3:
868 instruction->type = ARM_QDSUB;
869 mnemonic = "QDSUB";
870 break;
873 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s r%i, r%i, r%i",
874 address, opcode, mnemonic, COND(opcode), Rd, Rm, Rn);
877 /* Software breakpoints */
878 if ((opcode & 0x0000000f0) == 0x00000070)
880 uint32_t immediate;
881 instruction->type = ARM_BKPT;
882 immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
884 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tBKPT 0x%4.4x",
885 address, opcode, immediate);
888 /* Enhanced DSP multiplies */
889 if ((opcode & 0x000000090) == 0x00000080)
891 int x = (opcode & 0x20) >> 5;
892 int y = (opcode & 0x40) >> 6;
894 /* SMLA<x><y> */
895 if ((opcode & 0x00600000) == 0x00000000)
897 uint8_t Rd, Rm, Rs, Rn;
898 instruction->type = ARM_SMLAxy;
899 Rd = (opcode & 0xf0000) >> 16;
900 Rm = (opcode & 0xf);
901 Rs = (opcode & 0xf00) >> 8;
902 Rn = (opcode & 0xf000) >> 12;
904 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSMLA%s%s%s r%i, r%i, r%i, r%i",
905 address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
906 Rd, Rm, Rs, Rn);
909 /* SMLAL<x><y> */
910 if ((opcode & 0x00600000) == 0x00400000)
912 uint8_t RdLow, RdHi, Rm, Rs;
913 instruction->type = ARM_SMLAxy;
914 RdHi = (opcode & 0xf0000) >> 16;
915 RdLow = (opcode & 0xf000) >> 12;
916 Rm = (opcode & 0xf);
917 Rs = (opcode & 0xf00) >> 8;
919 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSMLA%s%s%s r%i, r%i, r%i, r%i",
920 address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
921 RdLow, RdHi, Rm, Rs);
924 /* SMLAW<y> */
925 if (((opcode & 0x00600000) == 0x00100000) && (x == 0))
927 uint8_t Rd, Rm, Rs, Rn;
928 instruction->type = ARM_SMLAWy;
929 Rd = (opcode & 0xf0000) >> 16;
930 Rm = (opcode & 0xf);
931 Rs = (opcode & 0xf00) >> 8;
932 Rn = (opcode & 0xf000) >> 12;
934 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSMLAW%s%s r%i, r%i, r%i, r%i",
935 address, opcode, (y) ? "T" : "B", COND(opcode),
936 Rd, Rm, Rs, Rn);
939 /* SMUL<x><y> */
940 if ((opcode & 0x00600000) == 0x00300000)
942 uint8_t Rd, Rm, Rs;
943 instruction->type = ARM_SMULxy;
944 Rd = (opcode & 0xf0000) >> 16;
945 Rm = (opcode & 0xf);
946 Rs = (opcode & 0xf00) >> 8;
948 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSMULW%s%s%s r%i, r%i, r%i",
949 address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
950 Rd, Rm, Rs);
953 /* SMULW<y> */
954 if (((opcode & 0x00600000) == 0x00100000) && (x == 1))
956 uint8_t Rd, Rm, Rs;
957 instruction->type = ARM_SMULWy;
958 Rd = (opcode & 0xf0000) >> 16;
959 Rm = (opcode & 0xf);
960 Rs = (opcode & 0xf00) >> 8;
962 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSMULW%s%s r%i, r%i, r%i",
963 address, opcode, (y) ? "T" : "B", COND(opcode),
964 Rd, Rm, Rs);
968 return ERROR_OK;
971 int evaluate_data_proc(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
973 uint8_t I, op, S, Rn, Rd;
974 char *mnemonic = NULL;
975 char shifter_operand[32];
977 I = (opcode & 0x02000000) >> 25;
978 op = (opcode & 0x01e00000) >> 21;
979 S = (opcode & 0x00100000) >> 20;
981 Rd = (opcode & 0xf000) >> 12;
982 Rn = (opcode & 0xf0000) >> 16;
984 instruction->info.data_proc.Rd = Rd;
985 instruction->info.data_proc.Rn = Rn;
986 instruction->info.data_proc.S = S;
988 switch (op)
990 case 0x0:
991 instruction->type = ARM_AND;
992 mnemonic = "AND";
993 break;
994 case 0x1:
995 instruction->type = ARM_EOR;
996 mnemonic = "EOR";
997 break;
998 case 0x2:
999 instruction->type = ARM_SUB;
1000 mnemonic = "SUB";
1001 break;
1002 case 0x3:
1003 instruction->type = ARM_RSB;
1004 mnemonic = "RSB";
1005 break;
1006 case 0x4:
1007 instruction->type = ARM_ADD;
1008 mnemonic = "ADD";
1009 break;
1010 case 0x5:
1011 instruction->type = ARM_ADC;
1012 mnemonic = "ADC";
1013 break;
1014 case 0x6:
1015 instruction->type = ARM_SBC;
1016 mnemonic = "SBC";
1017 break;
1018 case 0x7:
1019 instruction->type = ARM_RSC;
1020 mnemonic = "RSC";
1021 break;
1022 case 0x8:
1023 instruction->type = ARM_TST;
1024 mnemonic = "TST";
1025 break;
1026 case 0x9:
1027 instruction->type = ARM_TEQ;
1028 mnemonic = "TEQ";
1029 break;
1030 case 0xa:
1031 instruction->type = ARM_CMP;
1032 mnemonic = "CMP";
1033 break;
1034 case 0xb:
1035 instruction->type = ARM_CMN;
1036 mnemonic = "CMN";
1037 break;
1038 case 0xc:
1039 instruction->type = ARM_ORR;
1040 mnemonic = "ORR";
1041 break;
1042 case 0xd:
1043 instruction->type = ARM_MOV;
1044 mnemonic = "MOV";
1045 break;
1046 case 0xe:
1047 instruction->type = ARM_BIC;
1048 mnemonic = "BIC";
1049 break;
1050 case 0xf:
1051 instruction->type = ARM_MVN;
1052 mnemonic = "MVN";
1053 break;
1056 if (I) /* immediate shifter operand (#<immediate>)*/
1058 uint8_t immed_8 = opcode & 0xff;
1059 uint8_t rotate_imm = (opcode & 0xf00) >> 8;
1060 uint32_t immediate;
1062 immediate = ror(immed_8, rotate_imm * 2);
1064 snprintf(shifter_operand, 32, "#0x%x", immediate);
1066 instruction->info.data_proc.variant = 0;
1067 instruction->info.data_proc.shifter_operand.immediate.immediate = immediate;
1069 else /* register-based shifter operand */
1071 uint8_t shift, Rm;
1072 shift = (opcode & 0x60) >> 5;
1073 Rm = (opcode & 0xf);
1075 if ((opcode & 0x10) != 0x10) /* Immediate shifts ("<Rm>" or "<Rm>, <shift> #<shift_immediate>") */
1077 uint8_t shift_imm;
1078 shift_imm = (opcode & 0xf80) >> 7;
1080 instruction->info.data_proc.variant = 1;
1081 instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
1082 instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = shift_imm;
1083 instruction->info.data_proc.shifter_operand.immediate_shift.shift = shift;
1085 /* LSR encodes a shift by 32 bit as 0x0 */
1086 if ((shift == 0x1) && (shift_imm == 0x0))
1087 shift_imm = 0x20;
1089 /* ASR encodes a shift by 32 bit as 0x0 */
1090 if ((shift == 0x2) && (shift_imm == 0x0))
1091 shift_imm = 0x20;
1093 /* ROR by 32 bit is actually a RRX */
1094 if ((shift == 0x3) && (shift_imm == 0x0))
1095 shift = 0x4;
1097 if ((shift_imm == 0x0) && (shift == 0x0))
1099 snprintf(shifter_operand, 32, "r%i", Rm);
1101 else
1103 if (shift == 0x0) /* LSL */
1105 snprintf(shifter_operand, 32, "r%i, LSL #0x%x", Rm, shift_imm);
1107 else if (shift == 0x1) /* LSR */
1109 snprintf(shifter_operand, 32, "r%i, LSR #0x%x", Rm, shift_imm);
1111 else if (shift == 0x2) /* ASR */
1113 snprintf(shifter_operand, 32, "r%i, ASR #0x%x", Rm, shift_imm);
1115 else if (shift == 0x3) /* ROR */
1117 snprintf(shifter_operand, 32, "r%i, ROR #0x%x", Rm, shift_imm);
1119 else if (shift == 0x4) /* RRX */
1121 snprintf(shifter_operand, 32, "r%i, RRX", Rm);
1125 else /* Register shifts ("<Rm>, <shift> <Rs>") */
1127 uint8_t Rs = (opcode & 0xf00) >> 8;
1129 instruction->info.data_proc.variant = 2;
1130 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rm;
1131 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rs;
1132 instruction->info.data_proc.shifter_operand.register_shift.shift = shift;
1134 if (shift == 0x0) /* LSL */
1136 snprintf(shifter_operand, 32, "r%i, LSL r%i", Rm, Rs);
1138 else if (shift == 0x1) /* LSR */
1140 snprintf(shifter_operand, 32, "r%i, LSR r%i", Rm, Rs);
1142 else if (shift == 0x2) /* ASR */
1144 snprintf(shifter_operand, 32, "r%i, ASR r%i", Rm, Rs);
1146 else if (shift == 0x3) /* ROR */
1148 snprintf(shifter_operand, 32, "r%i, ROR r%i", Rm, Rs);
1153 if ((op < 0x8) || (op == 0xc) || (op == 0xe)) /* <opcode3>{<cond>}{S} <Rd>, <Rn>, <shifter_operand> */
1155 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, r%i, %s",
1156 address, opcode, mnemonic, COND(opcode),
1157 (S) ? "S" : "", Rd, Rn, shifter_operand);
1159 else if ((op == 0xd) || (op == 0xf)) /* <opcode1>{<cond>}{S} <Rd>, <shifter_operand> */
1161 if (opcode==0xe1a00000) /* print MOV r0,r0 as NOP */
1162 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tNOP",address, opcode);
1163 else
1164 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, %s",
1165 address, opcode, mnemonic, COND(opcode),
1166 (S) ? "S" : "", Rd, shifter_operand);
1168 else /* <opcode2>{<cond>} <Rn>, <shifter_operand> */
1170 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s r%i, %s",
1171 address, opcode, mnemonic, COND(opcode),
1172 Rn, shifter_operand);
1175 return ERROR_OK;
1178 int arm_evaluate_opcode(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
1180 /* clear fields, to avoid confusion */
1181 memset(instruction, 0, sizeof(arm_instruction_t));
1182 instruction->opcode = opcode;
1184 /* catch opcodes with condition field [31:28] = b1111 */
1185 if ((opcode & 0xf0000000) == 0xf0000000)
1187 /* Undefined instruction (or ARMv5E cache preload PLD) */
1188 if ((opcode & 0x08000000) == 0x00000000)
1189 return evaluate_pld(opcode, address, instruction);
1191 /* Undefined instruction */
1192 if ((opcode & 0x0e000000) == 0x08000000)
1194 instruction->type = ARM_UNDEFINED_INSTRUCTION;
1195 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
1196 return ERROR_OK;
1199 /* Branch and branch with link and change to Thumb */
1200 if ((opcode & 0x0e000000) == 0x0a000000)
1201 return evaluate_blx_imm(opcode, address, instruction);
1203 /* Extended coprocessor opcode space (ARMv5 and higher )*/
1204 /* Coprocessor load/store and double register transfers */
1205 if ((opcode & 0x0e000000) == 0x0c000000)
1206 return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
1208 /* Coprocessor data processing */
1209 if ((opcode & 0x0f000100) == 0x0c000000)
1210 return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1212 /* Coprocessor register transfers */
1213 if ((opcode & 0x0f000010) == 0x0c000010)
1214 return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1216 /* Undefined instruction */
1217 if ((opcode & 0x0f000000) == 0x0f000000)
1219 instruction->type = ARM_UNDEFINED_INSTRUCTION;
1220 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
1221 return ERROR_OK;
1225 /* catch opcodes with [27:25] = b000 */
1226 if ((opcode & 0x0e000000) == 0x00000000)
1228 /* Multiplies, extra load/stores */
1229 if ((opcode & 0x00000090) == 0x00000090)
1230 return evaluate_mul_and_extra_ld_st(opcode, address, instruction);
1232 /* Miscellaneous instructions */
1233 if ((opcode & 0x0f900000) == 0x01000000)
1234 return evaluate_misc_instr(opcode, address, instruction);
1236 return evaluate_data_proc(opcode, address, instruction);
1239 /* catch opcodes with [27:25] = b001 */
1240 if ((opcode & 0x0e000000) == 0x02000000)
1242 /* Undefined instruction */
1243 if ((opcode & 0x0fb00000) == 0x03000000)
1245 instruction->type = ARM_UNDEFINED_INSTRUCTION;
1246 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
1247 return ERROR_OK;
1250 /* Move immediate to status register */
1251 if ((opcode & 0x0fb00000) == 0x03200000)
1252 return evaluate_mrs_msr(opcode, address, instruction);
1254 return evaluate_data_proc(opcode, address, instruction);
1258 /* catch opcodes with [27:25] = b010 */
1259 if ((opcode & 0x0e000000) == 0x04000000)
1261 /* Load/store immediate offset */
1262 return evaluate_load_store(opcode, address, instruction);
1265 /* catch opcodes with [27:25] = b011 */
1266 if ((opcode & 0x0e000000) == 0x06000000)
1268 /* Undefined instruction */
1269 if ((opcode & 0x00000010) == 0x00000010)
1271 instruction->type = ARM_UNDEFINED_INSTRUCTION;
1272 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
1273 return ERROR_OK;
1276 /* Load/store register offset */
1277 return evaluate_load_store(opcode, address, instruction);
1281 /* catch opcodes with [27:25] = b100 */
1282 if ((opcode & 0x0e000000) == 0x08000000)
1284 /* Load/store multiple */
1285 return evaluate_ldm_stm(opcode, address, instruction);
1288 /* catch opcodes with [27:25] = b101 */
1289 if ((opcode & 0x0e000000) == 0x0a000000)
1291 /* Branch and branch with link */
1292 return evaluate_b_bl(opcode, address, instruction);
1295 /* catch opcodes with [27:25] = b110 */
1296 if ((opcode & 0x0e000000) == 0x0a000000)
1298 /* Coprocessor load/store and double register transfers */
1299 return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
1302 /* catch opcodes with [27:25] = b111 */
1303 if ((opcode & 0x0e000000) == 0x0e000000)
1305 /* Software interrupt */
1306 if ((opcode & 0x0f000000) == 0x0f000000)
1307 return evaluate_swi(opcode, address, instruction);
1309 /* Coprocessor data processing */
1310 if ((opcode & 0x0f000010) == 0x0e000000)
1311 return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1313 /* Coprocessor register transfers */
1314 if ((opcode & 0x0f000010) == 0x0e000010)
1315 return evaluate_cdp_mcr_mrc(opcode, address, instruction);
1318 LOG_ERROR("should never reach this point");
1319 return -1;
1322 int evaluate_b_bl_blx_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1324 uint32_t offset = opcode & 0x7ff;
1325 uint32_t opc = (opcode >> 11) & 0x3;
1326 uint32_t target_address;
1327 char *mnemonic = NULL;
1329 /* sign extend 11-bit offset */
1330 if (((opc==0) || (opc==2)) && (offset & 0x00000400))
1331 offset = 0xfffff800 | offset;
1333 target_address = address + 4 + (offset<<1);
1335 switch(opc)
1337 /* unconditional branch */
1338 case 0:
1339 instruction->type = ARM_B;
1340 mnemonic = "B";
1341 break;
1342 /* BLX suffix */
1343 case 1:
1344 instruction->type = ARM_BLX;
1345 mnemonic = "BLX";
1346 break;
1347 /* BL/BLX prefix */
1348 case 2:
1349 instruction->type = ARM_UNKNOWN_INSTUCTION;
1350 mnemonic = "prefix";
1351 target_address = offset<<12;
1352 break;
1353 /* BL suffix */
1354 case 3:
1355 instruction->type = ARM_BL;
1356 mnemonic = "BL";
1357 break;
1359 /* TODO: deals correctly with dual opcodes BL/BLX ... */
1361 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\t%s 0x%8.8x", address, opcode,mnemonic, target_address);
1363 instruction->info.b_bl_bx_blx.reg_operand = -1;
1364 instruction->info.b_bl_bx_blx.target_address = target_address;
1366 return ERROR_OK;
1369 int evaluate_add_sub_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1371 uint8_t Rd = (opcode >> 0) & 0x7;
1372 uint8_t Rn = (opcode >> 3) & 0x7;
1373 uint8_t Rm_imm = (opcode >> 6) & 0x7;
1374 uint32_t opc = opcode & (1<<9);
1375 uint32_t reg_imm = opcode & (1<<10);
1376 char *mnemonic;
1378 if (opc)
1380 instruction->type = ARM_SUB;
1381 mnemonic = "SUBS";
1383 else
1385 instruction->type = ARM_ADD;
1386 mnemonic = "ADDS";
1389 instruction->info.data_proc.Rd = Rd;
1390 instruction->info.data_proc.Rn = Rn;
1391 instruction->info.data_proc.S = 1;
1393 if (reg_imm)
1395 instruction->info.data_proc.variant = 0; /*immediate*/
1396 instruction->info.data_proc.shifter_operand.immediate.immediate = Rm_imm;
1397 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\t%s r%i, r%i, #%d",
1398 address, opcode, mnemonic, Rd, Rn, Rm_imm);
1400 else
1402 instruction->info.data_proc.variant = 1; /*immediate shift*/
1403 instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm_imm;
1404 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\t%s r%i, r%i, r%i",
1405 address, opcode, mnemonic, Rd, Rn, Rm_imm);
1408 return ERROR_OK;
1411 int evaluate_shift_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1413 uint8_t Rd = (opcode >> 0) & 0x7;
1414 uint8_t Rm = (opcode >> 3) & 0x7;
1415 uint8_t imm = (opcode >> 6) & 0x1f;
1416 uint8_t opc = (opcode >> 11) & 0x3;
1417 char *mnemonic = NULL;
1419 switch(opc)
1421 case 0:
1422 instruction->type = ARM_MOV;
1423 mnemonic = "LSLS";
1424 instruction->info.data_proc.shifter_operand.immediate_shift.shift = 0;
1425 break;
1426 case 1:
1427 instruction->type = ARM_MOV;
1428 mnemonic = "LSRS";
1429 instruction->info.data_proc.shifter_operand.immediate_shift.shift = 1;
1430 break;
1431 case 2:
1432 instruction->type = ARM_MOV;
1433 mnemonic = "ASRS";
1434 instruction->info.data_proc.shifter_operand.immediate_shift.shift = 2;
1435 break;
1438 if ((imm==0) && (opc!=0))
1439 imm = 32;
1441 instruction->info.data_proc.Rd = Rd;
1442 instruction->info.data_proc.Rn = -1;
1443 instruction->info.data_proc.S = 1;
1445 instruction->info.data_proc.variant = 1; /*immediate_shift*/
1446 instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
1447 instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = imm;
1449 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\t%s r%i, r%i, #0x%02x",
1450 address, opcode, mnemonic, Rd, Rm, imm);
1452 return ERROR_OK;
1455 int evaluate_data_proc_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1457 uint8_t imm = opcode & 0xff;
1458 uint8_t Rd = (opcode >> 8) & 0x7;
1459 uint32_t opc = (opcode >> 11) & 0x3;
1460 char *mnemonic = NULL;
1462 instruction->info.data_proc.Rd = Rd;
1463 instruction->info.data_proc.Rn = Rd;
1464 instruction->info.data_proc.S = 1;
1465 instruction->info.data_proc.variant = 0; /*immediate*/
1466 instruction->info.data_proc.shifter_operand.immediate.immediate = imm;
1468 switch(opc)
1470 case 0:
1471 instruction->type = ARM_MOV;
1472 mnemonic = "MOVS";
1473 instruction->info.data_proc.Rn = -1;
1474 break;
1475 case 1:
1476 instruction->type = ARM_CMP;
1477 mnemonic = "CMP";
1478 instruction->info.data_proc.Rd = -1;
1479 break;
1480 case 2:
1481 instruction->type = ARM_ADD;
1482 mnemonic = "ADDS";
1483 break;
1484 case 3:
1485 instruction->type = ARM_SUB;
1486 mnemonic = "SUBS";
1487 break;
1490 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\t%s r%i, #0x%02x",
1491 address, opcode, mnemonic, Rd, imm);
1493 return ERROR_OK;
1496 int evaluate_data_proc_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1498 uint8_t high_reg, op, Rm, Rd,H1,H2;
1499 char *mnemonic = NULL;
1501 high_reg = (opcode & 0x0400) >> 10;
1502 op = (opcode & 0x03C0) >> 6;
1504 Rd = (opcode & 0x0007);
1505 Rm = (opcode & 0x0038) >> 3;
1506 H1 = (opcode & 0x0080) >> 7;
1507 H2 = (opcode & 0x0040) >> 6;
1509 instruction->info.data_proc.Rd = Rd;
1510 instruction->info.data_proc.Rn = Rd;
1511 instruction->info.data_proc.S = (!high_reg || (instruction->type == ARM_CMP));
1512 instruction->info.data_proc.variant = 1 /*immediate shift*/;
1513 instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
1515 if (high_reg)
1517 Rd |= H1 << 3;
1518 Rm |= H2 << 3;
1519 op >>= 2;
1521 switch (op)
1523 case 0x0:
1524 instruction->type = ARM_ADD;
1525 mnemonic = "ADD";
1526 break;
1527 case 0x1:
1528 instruction->type = ARM_CMP;
1529 mnemonic = "CMP";
1530 break;
1531 case 0x2:
1532 instruction->type = ARM_MOV;
1533 mnemonic = "MOV";
1534 break;
1535 case 0x3:
1536 if ((opcode & 0x7) == 0x0)
1538 instruction->info.b_bl_bx_blx.reg_operand = Rm;
1539 if (H1)
1541 instruction->type = ARM_BLX;
1542 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\tBLX r%i", address, opcode, Rm);
1544 else
1546 instruction->type = ARM_BX;
1547 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\tBX r%i", address, opcode, Rm);
1550 else
1552 instruction->type = ARM_UNDEFINED_INSTRUCTION;
1553 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\tUNDEFINED INSTRUCTION", address, opcode);
1555 return ERROR_OK;
1556 break;
1559 else
1561 switch (op)
1563 case 0x0:
1564 instruction->type = ARM_AND;
1565 mnemonic = "ANDS";
1566 break;
1567 case 0x1:
1568 instruction->type = ARM_EOR;
1569 mnemonic = "EORS";
1570 break;
1571 case 0x2:
1572 instruction->type = ARM_MOV;
1573 mnemonic = "LSLS";
1574 instruction->info.data_proc.variant = 2 /*register shift*/;
1575 instruction->info.data_proc.shifter_operand.register_shift.shift = 0;
1576 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
1577 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
1578 break;
1579 case 0x3:
1580 instruction->type = ARM_MOV;
1581 mnemonic = "LSRS";
1582 instruction->info.data_proc.variant = 2 /*register shift*/;
1583 instruction->info.data_proc.shifter_operand.register_shift.shift = 1;
1584 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
1585 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
1586 break;
1587 case 0x4:
1588 instruction->type = ARM_MOV;
1589 mnemonic = "ASRS";
1590 instruction->info.data_proc.variant = 2 /*register shift*/;
1591 instruction->info.data_proc.shifter_operand.register_shift.shift = 2;
1592 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
1593 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
1594 break;
1595 case 0x5:
1596 instruction->type = ARM_ADC;
1597 mnemonic = "ADCS";
1598 break;
1599 case 0x6:
1600 instruction->type = ARM_SBC;
1601 mnemonic = "SBCS";
1602 break;
1603 case 0x7:
1604 instruction->type = ARM_MOV;
1605 mnemonic = "RORS";
1606 instruction->info.data_proc.variant = 2 /*register shift*/;
1607 instruction->info.data_proc.shifter_operand.register_shift.shift = 3;
1608 instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
1609 instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
1610 break;
1611 case 0x8:
1612 instruction->type = ARM_TST;
1613 mnemonic = "TST";
1614 break;
1615 case 0x9:
1616 instruction->type = ARM_RSB;
1617 mnemonic = "NEGS";
1618 instruction->info.data_proc.variant = 0 /*immediate*/;
1619 instruction->info.data_proc.shifter_operand.immediate.immediate = 0;
1620 instruction->info.data_proc.Rn = Rm;
1621 break;
1622 case 0xA:
1623 instruction->type = ARM_CMP;
1624 mnemonic = "CMP";
1625 break;
1626 case 0xB:
1627 instruction->type = ARM_CMN;
1628 mnemonic = "CMN";
1629 break;
1630 case 0xC:
1631 instruction->type = ARM_ORR;
1632 mnemonic = "ORRS";
1633 break;
1634 case 0xD:
1635 instruction->type = ARM_MUL;
1636 mnemonic = "MULS";
1637 break;
1638 case 0xE:
1639 instruction->type = ARM_BIC;
1640 mnemonic = "BICS";
1641 break;
1642 case 0xF:
1643 instruction->type = ARM_MVN;
1644 mnemonic = "MVNS";
1645 break;
1649 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\t%s r%i, r%i",
1650 address, opcode, mnemonic, Rd, Rm);
1652 return ERROR_OK;
1655 int evaluate_load_literal_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1657 uint32_t immediate;
1658 uint8_t Rd = (opcode >> 8) & 0x7;
1660 instruction->type = ARM_LDR;
1661 immediate = opcode & 0x000000ff;
1663 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\tLDR r%i, [PC, #0x%x]", address, opcode, Rd, immediate*4);
1665 instruction->info.load_store.Rd = Rd;
1666 instruction->info.load_store.Rn = 15 /*PC*/;
1667 instruction->info.load_store.index_mode = 0; /*offset*/
1668 instruction->info.load_store.offset_mode = 0; /*immediate*/
1669 instruction->info.load_store.offset.offset = immediate*4;
1671 return ERROR_OK;
1674 int evaluate_load_store_reg_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1676 uint8_t Rd = (opcode >> 0) & 0x7;
1677 uint8_t Rn = (opcode >> 3) & 0x7;
1678 uint8_t Rm = (opcode >> 6) & 0x7;
1679 uint8_t opc = (opcode >> 9) & 0x7;
1680 char *mnemonic = NULL;
1682 switch(opc)
1684 case 0:
1685 instruction->type = ARM_STR;
1686 mnemonic = "STR";
1687 break;
1688 case 1:
1689 instruction->type = ARM_STRH;
1690 mnemonic = "STRH";
1691 break;
1692 case 2:
1693 instruction->type = ARM_STRB;
1694 mnemonic = "STRB";
1695 break;
1696 case 3:
1697 instruction->type = ARM_LDRSB;
1698 mnemonic = "LDRSB";
1699 break;
1700 case 4:
1701 instruction->type = ARM_LDR;
1702 mnemonic = "LDR";
1703 break;
1704 case 5:
1705 instruction->type = ARM_LDRH;
1706 mnemonic = "LDRH";
1707 break;
1708 case 6:
1709 instruction->type = ARM_LDRB;
1710 mnemonic = "LDRB";
1711 break;
1712 case 7:
1713 instruction->type = ARM_LDRSH;
1714 mnemonic = "LDRSH";
1715 break;
1718 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\t%s r%i, [r%i, r%i]", address, opcode, mnemonic, Rd, Rn, Rm);
1720 instruction->info.load_store.Rd = Rd;
1721 instruction->info.load_store.Rn = Rn;
1722 instruction->info.load_store.index_mode = 0; /*offset*/
1723 instruction->info.load_store.offset_mode = 1; /*register*/
1724 instruction->info.load_store.offset.reg.Rm = Rm;
1726 return ERROR_OK;
1729 int evaluate_load_store_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1731 uint32_t offset = (opcode >> 6) & 0x1f;
1732 uint8_t Rd = (opcode >> 0) & 0x7;
1733 uint8_t Rn = (opcode >> 3) & 0x7;
1734 uint32_t L = opcode & (1<<11);
1735 uint32_t B = opcode & (1<<12);
1736 char *mnemonic;
1737 char suffix = ' ';
1738 uint32_t shift = 2;
1740 if (L)
1742 instruction->type = ARM_LDR;
1743 mnemonic = "LDR";
1745 else
1747 instruction->type = ARM_STR;
1748 mnemonic = "STR";
1751 if ((opcode&0xF000)==0x8000)
1753 suffix = 'H';
1754 shift = 1;
1756 else if (B)
1758 suffix = 'B';
1759 shift = 0;
1762 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\t%s%c r%i, [r%i, #0x%x]", address, opcode, mnemonic, suffix, Rd, Rn, offset<<shift);
1764 instruction->info.load_store.Rd = Rd;
1765 instruction->info.load_store.Rn = Rn;
1766 instruction->info.load_store.index_mode = 0; /*offset*/
1767 instruction->info.load_store.offset_mode = 0; /*immediate*/
1768 instruction->info.load_store.offset.offset = offset<<shift;
1770 return ERROR_OK;
1773 int evaluate_load_store_stack_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1775 uint32_t offset = opcode & 0xff;
1776 uint8_t Rd = (opcode >> 8) & 0x7;
1777 uint32_t L = opcode & (1<<11);
1778 char *mnemonic;
1780 if (L)
1782 instruction->type = ARM_LDR;
1783 mnemonic = "LDR";
1785 else
1787 instruction->type = ARM_STR;
1788 mnemonic = "STR";
1791 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\t%s r%i, [SP, #0x%x]", address, opcode, mnemonic, Rd, offset*4);
1793 instruction->info.load_store.Rd = Rd;
1794 instruction->info.load_store.Rn = 13 /*SP*/;
1795 instruction->info.load_store.index_mode = 0; /*offset*/
1796 instruction->info.load_store.offset_mode = 0; /*immediate*/
1797 instruction->info.load_store.offset.offset = offset*4;
1799 return ERROR_OK;
1802 int evaluate_add_sp_pc_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1804 uint32_t imm = opcode & 0xff;
1805 uint8_t Rd = (opcode >> 8) & 0x7;
1806 uint8_t Rn;
1807 uint32_t SP = opcode & (1<<11);
1808 char *reg_name;
1810 instruction->type = ARM_ADD;
1812 if (SP)
1814 reg_name = "SP";
1815 Rn = 13;
1817 else
1819 reg_name = "PC";
1820 Rn = 15;
1823 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\tADD r%i, %s, #0x%x", address, opcode, Rd,reg_name, imm*4);
1825 instruction->info.data_proc.variant = 0 /* immediate */;
1826 instruction->info.data_proc.Rd = Rd;
1827 instruction->info.data_proc.Rn = Rn;
1828 instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
1830 return ERROR_OK;
1833 int evaluate_adjust_stack_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1835 uint32_t imm = opcode & 0x7f;
1836 uint8_t opc = opcode & (1<<7);
1837 char *mnemonic;
1840 if (opc)
1842 instruction->type = ARM_SUB;
1843 mnemonic = "SUB";
1845 else
1847 instruction->type = ARM_ADD;
1848 mnemonic = "ADD";
1851 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\t%s SP, #0x%x", address, opcode, mnemonic, imm*4);
1853 instruction->info.data_proc.variant = 0 /* immediate */;
1854 instruction->info.data_proc.Rd = 13 /*SP*/;
1855 instruction->info.data_proc.Rn = 13 /*SP*/;
1856 instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
1858 return ERROR_OK;
1861 int evaluate_breakpoint_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1863 uint32_t imm = opcode & 0xff;
1865 instruction->type = ARM_BKPT;
1867 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\tBKPT 0x%02x", address, opcode, imm);
1869 return ERROR_OK;
1872 int evaluate_load_store_multiple_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1874 uint32_t reg_list = opcode & 0xff;
1875 uint32_t L = opcode & (1<<11);
1876 uint32_t R = opcode & (1<<8);
1877 uint8_t Rn = (opcode >> 8) & 7;
1878 uint8_t addr_mode = 0 /* IA */;
1879 char reg_names[40];
1880 char *reg_names_p;
1881 char *mnemonic;
1882 char ptr_name[7] = "";
1883 int i;
1885 if ((opcode & 0xf000) == 0xc000)
1886 { /* generic load/store multiple */
1887 if (L)
1889 instruction->type = ARM_LDM;
1890 mnemonic = "LDMIA";
1892 else
1894 instruction->type = ARM_STM;
1895 mnemonic = "STMIA";
1897 snprintf(ptr_name,7,"r%i!, ",Rn);
1899 else
1900 { /* push/pop */
1901 Rn = 13; /* SP */
1902 if (L)
1904 instruction->type = ARM_LDM;
1905 mnemonic = "POP";
1906 if (R)
1907 reg_list |= (1<<15) /*PC*/;
1909 else
1911 instruction->type = ARM_STM;
1912 mnemonic = "PUSH";
1913 addr_mode = 3; /*DB*/
1914 if (R)
1915 reg_list |= (1<<14) /*LR*/;
1919 reg_names_p = reg_names;
1920 for (i = 0; i <= 15; i++)
1922 if (reg_list & (1<<i))
1923 reg_names_p += snprintf(reg_names_p, (reg_names + 40 - reg_names_p), "r%i, ", i);
1925 if (reg_names_p>reg_names)
1926 reg_names_p[-2] = '\0';
1927 else /* invalid op : no registers */
1928 reg_names[0] = '\0';
1930 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\t%s %s{%s}", address, opcode, mnemonic, ptr_name,reg_names);
1932 instruction->info.load_store_multiple.register_list = reg_list;
1933 instruction->info.load_store_multiple.Rn = Rn;
1934 instruction->info.load_store_multiple.addressing_mode = addr_mode;
1936 return ERROR_OK;
1939 int evaluate_cond_branch_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1941 uint32_t offset = opcode & 0xff;
1942 uint8_t cond = (opcode >> 8) & 0xf;
1943 uint32_t target_address;
1945 if (cond == 0xf)
1947 instruction->type = ARM_SWI;
1948 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\tSWI 0x%02x", address, opcode, offset);
1949 return ERROR_OK;
1951 else if (cond == 0xe)
1953 instruction->type = ARM_UNDEFINED_INSTRUCTION;
1954 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\tUNDEFINED INSTRUCTION", address, opcode);
1955 return ERROR_OK;
1958 /* sign extend 8-bit offset */
1959 if (offset & 0x00000080)
1960 offset = 0xffffff00 | offset;
1962 target_address = address + 4 + (offset<<1);
1964 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\tB%s 0x%8.8x", address, opcode,
1965 arm_condition_strings[cond], target_address);
1967 instruction->type = ARM_B;
1968 instruction->info.b_bl_bx_blx.reg_operand = -1;
1969 instruction->info.b_bl_bx_blx.target_address = target_address;
1971 return ERROR_OK;
1974 int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
1976 /* clear fields, to avoid confusion */
1977 memset(instruction, 0, sizeof(arm_instruction_t));
1978 instruction->opcode = opcode;
1980 if ((opcode & 0xe000) == 0x0000)
1982 /* add/substract register or immediate */
1983 if ((opcode & 0x1800) == 0x1800)
1984 return evaluate_add_sub_thumb(opcode, address, instruction);
1985 /* shift by immediate */
1986 else
1987 return evaluate_shift_imm_thumb(opcode, address, instruction);
1990 /* Add/substract/compare/move immediate */
1991 if ((opcode & 0xe000) == 0x2000)
1993 return evaluate_data_proc_imm_thumb(opcode, address, instruction);
1996 /* Data processing instructions */
1997 if ((opcode & 0xf800) == 0x4000)
1999 return evaluate_data_proc_thumb(opcode, address, instruction);
2002 /* Load from literal pool */
2003 if ((opcode & 0xf800) == 0x4800)
2005 return evaluate_load_literal_thumb(opcode, address, instruction);
2008 /* Load/Store register offset */
2009 if ((opcode & 0xf000) == 0x5000)
2011 return evaluate_load_store_reg_thumb(opcode, address, instruction);
2014 /* Load/Store immediate offset */
2015 if (((opcode & 0xe000) == 0x6000)
2016 ||((opcode & 0xf000) == 0x8000))
2018 return evaluate_load_store_imm_thumb(opcode, address, instruction);
2021 /* Load/Store from/to stack */
2022 if ((opcode & 0xf000) == 0x9000)
2024 return evaluate_load_store_stack_thumb(opcode, address, instruction);
2027 /* Add to SP/PC */
2028 if ((opcode & 0xf000) == 0xa000)
2030 return evaluate_add_sp_pc_thumb(opcode, address, instruction);
2033 /* Misc */
2034 if ((opcode & 0xf000) == 0xb000)
2036 if ((opcode & 0x0f00) == 0x0000)
2037 return evaluate_adjust_stack_thumb(opcode, address, instruction);
2038 else if ((opcode & 0x0f00) == 0x0e00)
2039 return evaluate_breakpoint_thumb(opcode, address, instruction);
2040 else if ((opcode & 0x0600) == 0x0400) /* push pop */
2041 return evaluate_load_store_multiple_thumb(opcode, address, instruction);
2042 else
2044 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2045 snprintf(instruction->text, 128, "0x%8.8x\t0x%4.4x\tUNDEFINED INSTRUCTION", address, opcode);
2046 return ERROR_OK;
2050 /* Load/Store multiple */
2051 if ((opcode & 0xf000) == 0xc000)
2053 return evaluate_load_store_multiple_thumb(opcode, address, instruction);
2056 /* Conditional branch + SWI */
2057 if ((opcode & 0xf000) == 0xd000)
2059 return evaluate_cond_branch_thumb(opcode, address, instruction);
2062 if ((opcode & 0xe000) == 0xe000)
2064 /* Undefined instructions */
2065 if ((opcode & 0xf801) == 0xe801)
2067 instruction->type = ARM_UNDEFINED_INSTRUCTION;
2068 snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
2069 return ERROR_OK;
2071 else
2072 { /* Branch to offset */
2073 return evaluate_b_bl_blx_thumb(opcode, address, instruction);
2077 LOG_ERROR("should never reach this point (opcode=%04x)",opcode);
2078 return -1;
2081 int arm_access_size(arm_instruction_t *instruction)
2083 if ((instruction->type == ARM_LDRB)
2084 || (instruction->type == ARM_LDRBT)
2085 || (instruction->type == ARM_LDRSB)
2086 || (instruction->type == ARM_STRB)
2087 || (instruction->type == ARM_STRBT))
2089 return 1;
2091 else if ((instruction->type == ARM_LDRH)
2092 || (instruction->type == ARM_LDRSH)
2093 || (instruction->type == ARM_STRH))
2095 return 2;
2097 else if ((instruction->type == ARM_LDR)
2098 || (instruction->type == ARM_LDRT)
2099 || (instruction->type == ARM_STR)
2100 || (instruction->type == ARM_STRT))
2102 return 4;
2104 else if ((instruction->type == ARM_LDRD)
2105 || (instruction->type == ARM_STRD))
2107 return 8;
2109 else
2111 LOG_ERROR("BUG: instruction type %i isn't a load/store instruction", instruction->type);
2112 return 0;