#include "target.h"
#include "arm_disassembler.h"
-#include "log.h"
+#include <helper/log.h>
/*
* except as coprocessor 10/11 operations
* * Most ARM instructions through ARMv6 are decoded, but some
* of the post-ARMv4 opcodes may not be handled yet
+ * CPS, SDIV, UDIV, LDREX*, STREX*, QASX, ...
* * NEON instructions are not understood (ARMv7-A)
*
* - Thumb/Thumb2 decoding
return (value >> places) | (value << (32 - places));
}
+static int evaluate_unknown(uint32_t opcode,
+ uint32_t address, struct arm_instruction *instruction)
+{
+ instruction->type = ARM_UNDEFINED_INSTRUCTION;
+ snprintf(instruction->text, 128,
+ "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
+ "\tUNDEFINED INSTRUCTION", address, opcode);
+ return ERROR_OK;
+}
+
static int evaluate_pld(uint32_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
/* PLD */
if ((opcode & 0x0d70f000) == 0x0550f000)
return ERROR_OK;
}
- else
- {
- instruction->type = ARM_UNDEFINED_INSTRUCTION;
- return ERROR_OK;
+ return evaluate_unknown(opcode, address, instruction);
+}
+
+static int evaluate_srs(uint32_t opcode,
+ uint32_t address, struct arm_instruction *instruction)
+{
+ const char *wback = (opcode & (1 << 21)) ? "!" : "";
+ const char *mode = "";
+
+ switch ((opcode >> 23) & 0x3) {
+ case 0:
+ mode = "DA";
+ break;
+ case 1:
+ /* "IA" is default */
+ break;
+ case 2:
+ mode = "DB";
+ break;
+ case 3:
+ mode = "IB";
+ break;
}
- LOG_ERROR("should never reach this point");
- return -1;
+ switch (opcode & 0x0e500000) {
+ case 0x08400000:
+ snprintf(instruction->text, 128, "0x%8.8" PRIx32
+ "\t0x%8.8" PRIx32
+ "\tSRS%s\tSP%s, #%d",
+ address, opcode,
+ mode, wback,
+ (unsigned)(opcode & 0x1f));
+ break;
+ case 0x08100000:
+ snprintf(instruction->text, 128, "0x%8.8" PRIx32
+ "\t0x%8.8" PRIx32
+ "\tRFE%s\tr%d%s",
+ address, opcode,
+ mode,
+ (unsigned)((opcode >> 16) & 0xf), wback);
+ break;
+ default:
+ return evaluate_unknown(opcode, address, instruction);
+ }
+ return ERROR_OK;
}
static int evaluate_swi(uint32_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
instruction->type = ARM_SWI;
}
static int evaluate_blx_imm(uint32_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
int offset;
uint32_t immediate;
}
static int evaluate_b_bl(uint32_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint8_t L;
uint32_t immediate;
/* Coprocessor load/store and double register transfers */
/* both normal and extended instruction space (condition field b1111) */
static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint8_t cp_num = (opcode & 0xf00) >> 8;
mnemonic = "MRRC";
}
- snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s p%i, %x, r%i, r%i, c%i",
- address, opcode, mnemonic, COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm);
+ snprintf(instruction->text, 128,
+ "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
+ "\t%s%s%s p%i, %x, r%i, r%i, c%i",
+ address, opcode, mnemonic,
+ ((opcode & 0xf0000000) == 0xf0000000)
+ ? "2" : COND(opcode),
+ COND(opcode), cp_num, cp_opcode, Rd, Rn, CRm);
}
else /* LDC or STC */
{
CRd = (opcode & 0xf000) >> 12;
Rn = (opcode & 0xf0000) >> 16;
- offset = (opcode & 0xff);
+ offset = (opcode & 0xff) << 2;
/* load/store */
if (opcode & 0x00100000)
N = (opcode & 0x00400000) >> 22;
/* addressing modes */
- if ((opcode & 0x01200000) == 0x01000000) /* immediate offset */
- snprintf(addressing_mode, 32, "[r%i, #%s0x%2.2x*4]", Rn, (U) ? "" : "-", offset);
- else if ((opcode & 0x01200000) == 0x01200000) /* immediate pre-indexed */
- snprintf(addressing_mode, 32, "[r%i, #%s0x%2.2x*4]!", Rn, (U) ? "" : "-", offset);
- else if ((opcode & 0x01200000) == 0x00200000) /* immediate post-indexed */
- snprintf(addressing_mode, 32, "[r%i], #%s0x%2.2x*4", Rn, (U) ? "" : "-", offset);
+ if ((opcode & 0x01200000) == 0x01000000) /* offset */
+ snprintf(addressing_mode, 32, "[r%i, #%s%d]",
+ Rn, U ? "" : "-", offset);
+ else if ((opcode & 0x01200000) == 0x01200000) /* pre-indexed */
+ snprintf(addressing_mode, 32, "[r%i, #%s%d]!",
+ Rn, U ? "" : "-", offset);
+ else if ((opcode & 0x01200000) == 0x00200000) /* post-indexed */
+ snprintf(addressing_mode, 32, "[r%i], #%s%d",
+ Rn, U ? "" : "-", offset);
else if ((opcode & 0x01200000) == 0x00000000) /* unindexed */
- snprintf(addressing_mode, 32, "[r%i], #0x%2.2x", Rn, offset);
+ snprintf(addressing_mode, 32, "[r%i], {%d}",
+ Rn, offset >> 2);
- snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s p%i, c%i, %s",
- address, opcode, mnemonic, ((opcode & 0xf0000000) == 0xf0000000) ? COND(opcode) : "2",
- (N) ? "L" : "",
- cp_num, CRd, addressing_mode);
+ snprintf(instruction->text, 128, "0x%8.8" PRIx32
+ "\t0x%8.8" PRIx32
+ "\t%s%s%s p%i, c%i, %s",
+ address, opcode, mnemonic,
+ ((opcode & 0xf0000000) == 0xf0000000)
+ ? "2" : COND(opcode),
+ (opcode & (1 << 22)) ? "L" : "",
+ cp_num, CRd, addressing_mode);
}
return ERROR_OK;
/* Coprocessor register transfer instructions */
/* both normal and extended instruction space (condition field b1111) */
static int evaluate_cdp_mcr_mrc(uint32_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
const char *cond;
char* mnemonic;
/* Load/store instructions */
static int evaluate_load_store(uint32_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint8_t I, P, U, B, W, L;
uint8_t Rn, Rd;
/* ARMv6 and later support "media" instructions (includes SIMD) */
static int evaluate_media(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction)
+ struct arm_instruction *instruction)
{
char *cp = instruction->text;
char *mnemonic = NULL;
/* Miscellaneous load/store instructions */
static int evaluate_misc_load_store(uint32_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint8_t P, U, I, W, L, S, H;
uint8_t Rn, Rd;
/* Load/store multiples instructions */
static int evaluate_ldm_stm(uint32_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint8_t P, U, S, W, L, Rn;
uint32_t register_list;
}
}
- snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i%s, {%s}%s",
- address, opcode, mnemonic, COND(opcode), addressing_mode,
+ snprintf(instruction->text, 128,
+ "0x%8.8" PRIx32 "\t0x%8.8" PRIx32
+ "\t%s%s%s r%i%s, {%s}%s",
+ address, opcode,
+ mnemonic, addressing_mode, COND(opcode),
Rn, (W) ? "!" : "", reg_list, (S) ? "^" : "");
return ERROR_OK;
/* Multiplies, extra load/stores */
static int evaluate_mul_and_extra_ld_st(uint32_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
/* Multiply (accumulate) (long) and Swap/swap byte */
if ((opcode & 0x000000f0) == 0x00000090)
}
static int evaluate_mrs_msr(uint32_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
int R = (opcode & 0x00400000) >> 22;
char *PSR = (R) ? "SPSR" : "CPSR";
/* Miscellaneous instructions */
static int evaluate_misc_instr(uint32_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
/* MRS/MSR */
if ((opcode & 0x000000f0) == 0x00000000)
}
static int evaluate_data_proc(uint32_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint8_t I, op, S, Rn, Rd;
char *mnemonic = NULL;
return ERROR_OK;
}
-int arm_evaluate_opcode(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
+int arm_evaluate_opcode(uint32_t opcode, uint32_t address,
+ struct arm_instruction *instruction)
{
/* clear fields, to avoid confusion */
- memset(instruction, 0, sizeof(arm_instruction_t));
+ memset(instruction, 0, sizeof(struct arm_instruction));
instruction->opcode = opcode;
instruction->instruction_size = 4;
if ((opcode & 0x08000000) == 0x00000000)
return evaluate_pld(opcode, address, instruction);
- /* Undefined instruction */
+ /* Undefined instruction (or ARMv6+ SRS/RFE) */
if ((opcode & 0x0e000000) == 0x08000000)
- {
- instruction->type = ARM_UNDEFINED_INSTRUCTION;
- snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
- return ERROR_OK;
- }
+ return evaluate_srs(opcode, address, instruction);
/* Branch and branch with link and change to Thumb */
if ((opcode & 0x0e000000) == 0x0a000000)
}
/* catch opcodes with [27:25] = b110 */
- if ((opcode & 0x0e000000) == 0x0a000000)
+ if ((opcode & 0x0e000000) == 0x0c000000)
{
/* Coprocessor load/store and double register transfers */
return evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);
return evaluate_cdp_mcr_mrc(opcode, address, instruction);
}
- LOG_ERROR("should never reach this point");
+ LOG_ERROR("ARM: should never reach this point (opcode=%08x)",
+ (unsigned) opcode);
return -1;
}
static int evaluate_b_bl_blx_thumb(uint16_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint32_t offset = opcode & 0x7ff;
uint32_t opc = (opcode >> 11) & 0x3;
}
/* TODO: deal correctly with dual opcode (prefixed) BL/BLX;
- * these are effectively 32-bit instructions even in Thumb1.
- * Might be simplest to always use the Thumb2 decoder.
+ * these are effectively 32-bit instructions even in Thumb1. For
+ * disassembly, it's simplest to always use the Thumb2 decoder.
+ *
+ * But some cores will evidently handle them as two instructions,
+ * where exceptions may occur between the two. The ETMv3.2+ ID
+ * register has a bit which exposes this behavior.
*/
snprintf(instruction->text, 128,
}
static int evaluate_add_sub_thumb(uint16_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint8_t Rd = (opcode >> 0) & 0x7;
uint8_t Rn = (opcode >> 3) & 0x7;
}
static int evaluate_shift_imm_thumb(uint16_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint8_t Rd = (opcode >> 0) & 0x7;
uint8_t Rm = (opcode >> 3) & 0x7;
}
static int evaluate_data_proc_imm_thumb(uint16_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint8_t imm = opcode & 0xff;
uint8_t Rd = (opcode >> 8) & 0x7;
}
static int evaluate_data_proc_thumb(uint16_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint8_t high_reg, op, Rm, Rd,H1,H2;
char *mnemonic = NULL;
}
static int evaluate_load_literal_thumb(uint16_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint32_t immediate;
uint8_t Rd = (opcode >> 8) & 0x7;
}
static int evaluate_load_store_reg_thumb(uint16_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint8_t Rd = (opcode >> 0) & 0x7;
uint8_t Rn = (opcode >> 3) & 0x7;
}
static int evaluate_load_store_imm_thumb(uint16_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint32_t offset = (opcode >> 6) & 0x1f;
uint8_t Rd = (opcode >> 0) & 0x7;
}
static int evaluate_load_store_stack_thumb(uint16_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint32_t offset = opcode & 0xff;
uint8_t Rd = (opcode >> 8) & 0x7;
}
static int evaluate_add_sp_pc_thumb(uint16_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint32_t imm = opcode & 0xff;
uint8_t Rd = (opcode >> 8) & 0x7;
}
static int evaluate_adjust_stack_thumb(uint16_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint32_t imm = opcode & 0x7f;
uint8_t opc = opcode & (1 << 7);
}
static int evaluate_breakpoint_thumb(uint16_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint32_t imm = opcode & 0xff;
}
static int evaluate_load_store_multiple_thumb(uint16_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint32_t reg_list = opcode & 0xff;
uint32_t L = opcode & (1 << 11);
}
static int evaluate_cond_branch_thumb(uint16_t opcode,
- uint32_t address, arm_instruction_t *instruction)
+ uint32_t address, struct arm_instruction *instruction)
{
uint32_t offset = opcode & 0xff;
uint8_t cond = (opcode >> 8) & 0xf;
}
static int evaluate_cb_thumb(uint16_t opcode, uint32_t address,
- arm_instruction_t *instruction)
+ struct arm_instruction *instruction)
{
unsigned offset;
}
static int evaluate_extend_thumb(uint16_t opcode, uint32_t address,
- arm_instruction_t *instruction)
+ struct arm_instruction *instruction)
{
/* added in ARMv6 */
snprintf(instruction->text, 128,
}
static int evaluate_cps_thumb(uint16_t opcode, uint32_t address,
- arm_instruction_t *instruction)
+ struct arm_instruction *instruction)
{
/* added in ARMv6 */
if ((opcode & 0x0ff0) == 0x0650)
}
static int evaluate_byterev_thumb(uint16_t opcode, uint32_t address,
- arm_instruction_t *instruction)
+ struct arm_instruction *instruction)
{
char *suffix;
}
static int evaluate_hint_thumb(uint16_t opcode, uint32_t address,
- arm_instruction_t *instruction)
+ struct arm_instruction *instruction)
{
char *hint;
}
static int evaluate_ifthen_thumb(uint16_t opcode, uint32_t address,
- arm_instruction_t *instruction)
+ struct arm_instruction *instruction)
{
unsigned cond = (opcode >> 4) & 0x0f;
char *x = "", *y = "", *z = "";
return ERROR_OK;
}
-int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
+int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, struct arm_instruction *instruction)
{
/* clear fields, to avoid confusion */
- memset(instruction, 0, sizeof(arm_instruction_t));
+ memset(instruction, 0, sizeof(struct arm_instruction));
instruction->opcode = opcode;
instruction->instruction_size = 2;
}
}
- LOG_ERROR("should never reach this point (opcode=%04x)",opcode);
+ LOG_ERROR("Thumb: should never reach this point (opcode=%04x)", opcode);
return -1;
}
static int t2ev_b_bl(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
unsigned offset;
unsigned b21 = 1 << 21;
}
static int t2ev_cond_b(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
unsigned offset;
unsigned b17 = 1 << 17;
}
static int t2ev_hint(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
const char *mnemonic;
}
static int t2ev_misc(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
const char *mnemonic;
}
static int t2ev_b_misc(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
/* permanently undefined */
if ((opcode & 0x07f07000) == 0x07f02000) {
}
static int t2ev_data_mod_immed(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
char *mnemonic = NULL;
int rn = (opcode >> 16) & 0xf;
}
static int t2ev_data_immed(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
char *mnemonic = NULL;
int rn = (opcode >> 16) & 0xf;
case 0x0c:
/* move constant to top 16 bits of register */
immed |= (opcode >> 4) & 0xf000;
- sprintf(cp, "MOVT\tr%d, #%d\t; %#4.4x", rn, immed, immed);
+ sprintf(cp, "MOVT\tr%d, #%d\t; %#4.4x", rd, immed, immed);
return ERROR_OK;
case 0x10:
case 0x12:
}
static int t2ev_store_single(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
unsigned op = (opcode >> 20) & 0xf;
char *size = "";
}
static int t2ev_mul32(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
int ra = (opcode >> 12) & 0xf;
}
static int t2ev_mul64_div(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
int op = (opcode >> 4) & 0xf;
char *infix = "MUL";
}
static int t2ev_ldm_stm(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
int rn = (opcode >> 16) & 0xf;
int op = (opcode >> 22) & 0x6;
int t = (opcode >> 21) & 1;
unsigned registers = opcode & 0xffff;
+ char *mode = "";
if (opcode & (1 << 20))
op |= 1;
switch (op) {
+ case 0:
+ mode = "DB";
+ /* FALL THROUGH */
+ case 6:
+ sprintf(cp, "SRS%s\tsp%s, #%d", mode,
+ t ? "!" : "",
+ (unsigned) (opcode & 0x1f));
+ return ERROR_OK;
+ case 1:
+ mode = "DB";
+ /* FALL THROUGH */
+ case 7:
+ sprintf(cp, "RFE%s\tr%d%s", mode,
+ (unsigned) ((opcode >> 16) & 0xf),
+ t ? "!" : "");
+ return ERROR_OK;
case 2:
sprintf(cp, "STM.W\tr%d%s, ", rn, t ? "!" : "");
break;
/* load/store dual or exclusive, table branch */
static int t2ev_ldrex_strex(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
unsigned op1op2 = (opcode >> 20) & 0x3;
unsigned op3 = (opcode >> 4) & 0xf;
}
static int t2ev_data_shift(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
int op = (opcode >> 21) & 0xf;
int rd = (opcode >> 8) & 0xf;
}
static int t2ev_data_reg(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
char *mnemonic;
char * suffix = "";
}
static int t2ev_load_word(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
int rn = (opcode >> 16) & 0xf;
int immed;
}
static int t2ev_load_byte_hints(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
int rn = (opcode >> 16) & 0xf;
int rt = (opcode >> 12) & 0xf;
}
static int t2ev_load_halfword(uint32_t opcode, uint32_t address,
- arm_instruction_t *instruction, char *cp)
+ struct arm_instruction *instruction, char *cp)
{
int rn = (opcode >> 16) & 0xf;
int rt = (opcode >> 12) & 0xf;
* always set. That means eventual arm_simulate_step() support for Thumb2
* will need work in this area.
*/
-int thumb2_opcode(target_t *target, uint32_t address, arm_instruction_t *instruction)
+int thumb2_opcode(struct target *target, uint32_t address, struct arm_instruction *instruction)
{
int retval;
uint16_t op;
address &= ~1;
/* clear fields, to avoid confusion */
- memset(instruction, 0, sizeof(arm_instruction_t));
+ memset(instruction, 0, sizeof(struct arm_instruction));
/* read first halfword, see if this is the only one */
retval = target_read_u16(target, address, &op);
return ERROR_OK;
}
-int arm_access_size(arm_instruction_t *instruction)
+int arm_access_size(struct arm_instruction *instruction)
{
if ((instruction->type == ARM_LDRB)
|| (instruction->type == ARM_LDRBT)