- Fixes '<<' whitespace
[openocd.git] / src / target / arm_disassembler.c
index f9e0227af8e952997a6dbad4d50bab738e559b5c..b314e02a19e7a880c2f6edda7fdbfd9c60456cff 100644 (file)
 #endif
 
 #include "arm_disassembler.h"
-
 #include "log.h"
 
-#include <string.h>
 
 /* textual represenation of the condition field */
 /* ALways (default) is ommitted (empty string) */
@@ -35,19 +33,19 @@ char *arm_condition_strings[] =
 };
 
 /* make up for C's missing ROR */
-u32 ror(u32 value, int places) 
+uint32_t ror(uint32_t value, int places) 
 { 
        return (value >> places) | (value << (32 - places)); 
 }
 
-int evaluate_pld(u32 opcode, u32 address, arm_instruction_t *instruction)
+int evaluate_pld(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
 {
        /* PLD */
        if ((opcode & 0x0d70f0000) == 0x0550f000)
        {
                instruction->type = ARM_PLD;
                
-               snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tPLD ...TODO...", address, opcode);
+               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tPLD ...TODO...", address, opcode);
                
                return ERROR_OK;
        }
@@ -57,24 +55,24 @@ int evaluate_pld(u32 opcode, u32 address, arm_instruction_t *instruction)
                return ERROR_OK;
        }
        
-       ERROR("should never reach this point");
+       LOG_ERROR("should never reach this point");
        return -1;
 }
 
-int evaluate_swi(u32 opcode, u32 address, arm_instruction_t *instruction)
+int evaluate_swi(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
 {
        instruction->type = ARM_SWI;
        
-       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSWI 0x%6.6x", address, opcode, (opcode & 0xffffff));
+       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSWI 0x%6.6" PRIx32 "", address, opcode, (opcode & 0xffffff));
        
        return ERROR_OK;
 }
 
-int evaluate_blx_imm(u32 opcode, u32 address, arm_instruction_t *instruction)
+int evaluate_blx_imm(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
 {
        int offset;
-       u32 immediate;
-       u32 target_address;
+       uint32_t immediate;
+       uint32_t target_address;
        
        instruction->type = ARM_BLX;
        immediate = opcode & 0x00ffffff;
@@ -94,7 +92,7 @@ int evaluate_blx_imm(u32 opcode, u32 address, arm_instruction_t *instruction)
        
        target_address = address + 8 + offset;
        
-       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tBLX 0x%8.8x", address, opcode, target_address);
+       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX 0x%8.8" PRIx32 "", address, opcode, target_address);
        
        instruction->info.b_bl_bx_blx.reg_operand = -1;
        instruction->info.b_bl_bx_blx.target_address = target_address;
@@ -102,12 +100,12 @@ int evaluate_blx_imm(u32 opcode, u32 address, arm_instruction_t *instruction)
        return ERROR_OK;
 }
 
-int evaluate_b_bl(u32 opcode, u32 address, arm_instruction_t *instruction)
+int evaluate_b_bl(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
 {
-       u8 L;
-       u32 immediate;
+       uint8_t L;
+       uint32_t immediate;
        int offset;
-       u32 target_address;
+       uint32_t target_address;
        
        immediate = opcode & 0x00ffffff;
        L = (opcode & 0x01000000) >> 24;
@@ -128,7 +126,7 @@ int evaluate_b_bl(u32 opcode, u32 address, arm_instruction_t *instruction)
        else
                instruction->type = ARM_B;
        
-       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tB%s%s 0x%8.8x", address, opcode,
+       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tB%s%s 0x%8.8" PRIx32 , address, opcode,
                         (L) ? "L" : "", COND(opcode), target_address);
        
        instruction->info.b_bl_bx_blx.reg_operand = -1;
@@ -139,14 +137,14 @@ int evaluate_b_bl(u32 opcode, u32 address, arm_instruction_t *instruction)
 
 /* Coprocessor load/store and double register transfers */
 /* both normal and extended instruction space (condition field b1111) */
-int evaluate_ldc_stc_mcrr_mrrc(u32 opcode, u32 address, arm_instruction_t *instruction)
+int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
 {
-       u8 cp_num = (opcode & 0xf00) >> 8;
+       uint8_t cp_num = (opcode & 0xf00) >> 8;
        
        /* MCRR or MRRC */
        if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c400000))
        {
-               u8 cp_opcode, Rd, Rn, CRm;
+               uint8_t cp_opcode, Rd, Rn, CRm;
                char *mnemonic;
                
                cp_opcode = (opcode & 0xf0) >> 4;
@@ -168,13 +166,13 @@ int evaluate_ldc_stc_mcrr_mrrc(u32 opcode, u32 address, arm_instruction_t *instr
                        mnemonic = "MRRC";
                }
                
-               snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s p%i, %x, r%i, r%i, c%i",
+               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);
        }
        else /* LDC or STC */
        {
-               u8 CRd, Rn, offset;
-               u8 U, N;
+               uint8_t CRd, Rn, offset;
+               uint8_t U, N;
                char *mnemonic;
                char addressing_mode[32];
                
@@ -207,7 +205,7 @@ int evaluate_ldc_stc_mcrr_mrrc(u32 opcode, u32 address, arm_instruction_t *instr
                else if ((opcode & 0x01200000) == 0x00000000) /* unindexed */
                        snprintf(addressing_mode, 32, "[r%i], #0x%2.2x", Rn, offset);
 
-               snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s p%i, c%i, %s",
+               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);
@@ -219,11 +217,11 @@ int evaluate_ldc_stc_mcrr_mrrc(u32 opcode, u32 address, arm_instruction_t *instr
 /* Coprocessor data processing instructions */
 /* Coprocessor register transfer instructions */
 /* both normal and extended instruction space (condition field b1111) */
-int evaluate_cdp_mcr_mrc(u32 opcode, u32 address, arm_instruction_t *instruction)
+int evaluate_cdp_mcr_mrc(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
 {
        char* cond;
        char* mnemonic;
-       u8 cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2;
+       uint8_t cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2;
        
        cond = ((opcode & 0xf0000000) == 0xf0000000) ? "2" : COND(opcode);
        cp_num = (opcode & 0xf00) >> 8;
@@ -248,7 +246,7 @@ int evaluate_cdp_mcr_mrc(u32 opcode, u32 address, arm_instruction_t *instruction
                
                opcode_1 = (opcode & 0x00e00000) >> 21;
                
-               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",
+               snprintf(instruction->text, 128, "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",
                                 address, opcode, mnemonic, cond,
                                 cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2);
        }
@@ -259,7 +257,7 @@ int evaluate_cdp_mcr_mrc(u32 opcode, u32 address, arm_instruction_t *instruction
                
                opcode_1 = (opcode & 0x00f00000) >> 20;
                
-               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",
+               snprintf(instruction->text, 128, "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",
                                 address, opcode, mnemonic, cond,
                                 cp_num, opcode_1, CRd_Rd, CRn, CRm, opcode_2);
        }
@@ -268,10 +266,10 @@ int evaluate_cdp_mcr_mrc(u32 opcode, u32 address, arm_instruction_t *instruction
 }
 
 /* Load/store instructions */
-int evaluate_load_store(u32 opcode, u32 address, arm_instruction_t *instruction)
+int evaluate_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
 {
-       u8 I, P, U, B, W, L;
-       u8 Rn, Rd;
+       uint8_t I, P, U, B, W, L;
+       uint8_t Rn, Rd;
        char *operation; /* "LDR" or "STR" */
        char *suffix; /* "", "B", "T", "BT" */
        char offset[32];
@@ -342,16 +340,19 @@ int evaluate_load_store(u32 opcode, u32 address, arm_instruction_t *instruction)
        
        if (!I) /* #+-<offset_12> */
        {
-               u32 offset_12 = (opcode & 0xfff);
-               snprintf(offset, 32, "#%s0x%x", (U) ? "" : "-", offset_12);
+               uint32_t offset_12 = (opcode & 0xfff);
+               if (offset_12)
+                       snprintf(offset, 32, ", #%s0x%" PRIx32 "", (U) ? "" : "-", offset_12);
+               else
+                       snprintf(offset, 32, "%s", "");
                
                instruction->info.load_store.offset_mode = 0;
                instruction->info.load_store.offset.offset = offset_12;
        }
        else /* either +-<Rm> or +-<Rm>, <shift>, #<shift_imm> */
        {
-               u8 shift_imm, shift;
-               u8 Rm;
+               uint8_t shift_imm, shift;
+               uint8_t Rm;
                
                shift_imm = (opcode & 0xf80) >> 7;
                shift = (opcode & 0x60) >> 5;
@@ -376,26 +377,26 @@ int evaluate_load_store(u32 opcode, u32 address, arm_instruction_t *instruction)
 
                if ((shift_imm == 0x0) && (shift == 0x0)) /* +-<Rm> */
                {
-                       snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm);
+                       snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm);
                }
                else /* +-<Rm>, <Shift>, #<shift_imm> */
                {
                        switch (shift)
                        {
                                case 0x0: /* LSL */
-                                       snprintf(offset, 32, "%sr%i, LSL #0x%x", (U) ? "" : "-", Rm, shift_imm);
+                                       snprintf(offset, 32, "%sr%i, LSL #0x%x", (U) ? "" : "-", Rm, shift_imm);
                                        break;
                                case 0x1: /* LSR */
-                                       snprintf(offset, 32, "%sr%i, LSR #0x%x", (U) ? "" : "-", Rm, shift_imm);
+                                       snprintf(offset, 32, "%sr%i, LSR #0x%x", (U) ? "" : "-", Rm, shift_imm);
                                        break;
                                case 0x2: /* ASR */
-                                       snprintf(offset, 32, "%sr%i, ASR #0x%x", (U) ? "" : "-", Rm, shift_imm);
+                                       snprintf(offset, 32, "%sr%i, ASR #0x%x", (U) ? "" : "-", Rm, shift_imm);
                                        break;
                                case 0x3: /* ROR */
-                                       snprintf(offset, 32, "%sr%i, ROR #0x%x", (U) ? "" : "-", Rm, shift_imm);
+                                       snprintf(offset, 32, "%sr%i, ROR #0x%x", (U) ? "" : "-", Rm, shift_imm);
                                        break;
                                case 0x4: /* RRX */
-                                       snprintf(offset, 32, "%sr%i, RRX", (U) ? "" : "-", Rm);
+                                       snprintf(offset, 32, "%sr%i, RRX", (U) ? "" : "-", Rm);
                                        break;
                        }
                }
@@ -405,7 +406,7 @@ int evaluate_load_store(u32 opcode, u32 address, arm_instruction_t *instruction)
        {
                if (W == 0) /* offset */
                {
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i, %s]",
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]",
                                         address, opcode, operation, COND(opcode), suffix,
                                         Rd, Rn, offset);
                        
@@ -413,7 +414,7 @@ int evaluate_load_store(u32 opcode, u32 address, arm_instruction_t *instruction)
                }
                else /* pre-indexed */
                {
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i, %s]!",
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i%s]!",
                                         address, opcode, operation, COND(opcode), suffix,
                                         Rd, Rn, offset);
                        
@@ -422,7 +423,7 @@ int evaluate_load_store(u32 opcode, u32 address, arm_instruction_t *instruction)
        }
        else /* post-indexed */
        {
-               snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i], %s",
+               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i]%s",
                                 address, opcode, operation, COND(opcode), suffix,
                                 Rd, Rn, offset);
                
@@ -433,10 +434,10 @@ int evaluate_load_store(u32 opcode, u32 address, arm_instruction_t *instruction)
 }
 
 /* Miscellaneous load/store instructions */
-int evaluate_misc_load_store(u32 opcode, u32 address, arm_instruction_t *instruction)
+int evaluate_misc_load_store(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
 {
-       u8 P, U, I, W, L, S, H;
-       u8 Rn, Rd;
+       uint8_t P, U, I, W, L, S, H;
+       uint8_t Rn, Rd;
        char *operation; /* "LDR" or "STR" */
        char *suffix; /* "H", "SB", "SH", "D" */
        char offset[32];
@@ -510,15 +511,15 @@ int evaluate_misc_load_store(u32 opcode, u32 address, arm_instruction_t *instruc
        
        if (I) /* Immediate offset/index (#+-<offset_8>)*/
        {
-               u32 offset_8 = ((opcode & 0xf00) >> 4) | (opcode & 0xf);
-               snprintf(offset, 32, "#%s0x%x", (U) ? "" : "-", offset_8);
+               uint32_t offset_8 = ((opcode & 0xf00) >> 4) | (opcode & 0xf);
+               snprintf(offset, 32, "#%s0x%" PRIx32 "", (U) ? "" : "-", offset_8);
                
                instruction->info.load_store.offset_mode = 0;
                instruction->info.load_store.offset.offset = offset_8;
        }
        else /* Register offset/index (+-<Rm>) */
        {
-               u8 Rm;
+               uint8_t Rm;
                Rm = (opcode & 0xf);
                snprintf(offset, 32, "%sr%i", (U) ? "" : "-", Rm);
                
@@ -532,7 +533,7 @@ int evaluate_misc_load_store(u32 opcode, u32 address, arm_instruction_t *instruc
        {
                if (W == 0) /* offset */
                {
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i, %s]",
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]",
                                         address, opcode, operation, COND(opcode), suffix,
                                         Rd, Rn, offset);
                        
@@ -540,7 +541,7 @@ int evaluate_misc_load_store(u32 opcode, u32 address, arm_instruction_t *instruc
                }
                else /* pre-indexed */
                {
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i, %s]!",
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i, %s]!",
                                         address, opcode, operation, COND(opcode), suffix,
                                         Rd, Rn, offset);
                
@@ -549,7 +550,7 @@ int evaluate_misc_load_store(u32 opcode, u32 address, arm_instruction_t *instruc
        }
        else /* post-indexed */
        {
-               snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, [r%i], %s",
+               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, [r%i], %s",
                                 address, opcode, operation, COND(opcode), suffix,
                                 Rd, Rn, offset);
        
@@ -560,10 +561,10 @@ int evaluate_misc_load_store(u32 opcode, u32 address, arm_instruction_t *instruc
 }
 
 /* Load/store multiples instructions */
-int evaluate_ldm_stm(u32 opcode, u32 address, arm_instruction_t *instruction)
+int evaluate_ldm_stm(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
 {
-       u8 P, U, S, W, L, Rn;
-       u32 register_list;
+       uint8_t P, U, S, W, L, Rn;
+       uint32_t register_list;
        char *addressing_mode;
        char *mnemonic;
        char reg_list[69];
@@ -639,7 +640,7 @@ int evaluate_ldm_stm(u32 opcode, u32 address, arm_instruction_t *instruction)
                }
        }
        
-       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i%s, {%s}%s",
+       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,
                         Rn, (W) ? "!" : "", reg_list, (S) ? "^" : "");
        
@@ -647,7 +648,7 @@ int evaluate_ldm_stm(u32 opcode, u32 address, arm_instruction_t *instruction)
 }
 
 /* Multiplies, extra load/stores */
-int evaluate_mul_and_extra_ld_st(u32 opcode, u32 address, arm_instruction_t *instruction)
+int evaluate_mul_and_extra_ld_st(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
 {
        /* Multiply (accumulate) (long) and Swap/swap byte */
        if ((opcode & 0x000000f0) == 0x00000090)
@@ -655,7 +656,7 @@ int evaluate_mul_and_extra_ld_st(u32 opcode, u32 address, arm_instruction_t *ins
                /* Multiply (accumulate) */
                if ((opcode & 0x0f800000) == 0x00000000)
                {
-                       u8 Rm, Rs, Rn, Rd, S;
+                       uint8_t Rm, Rs, Rn, Rd, S;
                        Rm = opcode & 0xf;
                        Rs = (opcode & 0xf00) >> 8;
                        Rn = (opcode & 0xf000) >> 12;
@@ -666,13 +667,13 @@ int evaluate_mul_and_extra_ld_st(u32 opcode, u32 address, arm_instruction_t *ins
                        if (opcode & 0x00200000)
                        {
                                instruction->type = ARM_MLA;
-                               snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tMLA%s%s r%i, r%i, r%i, r%i",
+                               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMLA%s%s r%i, r%i, r%i, r%i",
                                                address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs, Rn);
                        }
                        else
                        {
                                instruction->type = ARM_MUL;
-                               snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tMUL%s%s r%i, r%i, r%i",
+                               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMUL%s%s r%i, r%i, r%i",
                                                 address, opcode, COND(opcode), (S) ? "S" : "", Rd, Rm, Rs);
                        }
                        
@@ -683,7 +684,7 @@ int evaluate_mul_and_extra_ld_st(u32 opcode, u32 address, arm_instruction_t *ins
                if ((opcode & 0x0f800000) == 0x00800000)
                {
                        char* mnemonic = NULL;
-                       u8 Rm, Rs, RdHi, RdLow, S;
+                       uint8_t Rm, Rs, RdHi, RdLow, S;
                        Rm = opcode & 0xf;
                        Rs = (opcode & 0xf00) >> 8;
                        RdHi = (opcode & 0xf000) >> 12;
@@ -710,7 +711,7 @@ int evaluate_mul_and_extra_ld_st(u32 opcode, u32 address, arm_instruction_t *ins
                                        break;
                        }
                        
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, r%i, r%i, r%i",
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, r%i, r%i",
                                                address, opcode, mnemonic, COND(opcode), (S) ? "S" : "",
                                                RdLow, RdHi, Rm, Rs);
                        
@@ -720,7 +721,7 @@ int evaluate_mul_and_extra_ld_st(u32 opcode, u32 address, arm_instruction_t *ins
                /* Swap/swap byte */
                if ((opcode & 0x0f800000) == 0x01000000)
                {
-                       u8 Rm, Rd, Rn;
+                       uint8_t Rm, Rd, Rn;
                        Rm = opcode & 0xf;
                        Rd = (opcode & 0xf000) >> 12;
                        Rn = (opcode & 0xf0000) >> 16;
@@ -728,7 +729,7 @@ int evaluate_mul_and_extra_ld_st(u32 opcode, u32 address, arm_instruction_t *ins
                        /* examine B flag */
                        instruction->type = (opcode & 0x00400000) ? ARM_SWPB : ARM_SWP;
                        
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s r%i, r%i, [r%i]",
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, [r%i]",
                                         address, opcode, (opcode & 0x00400000) ? "SWPB" : "SWP", COND(opcode), Rd, Rm, Rn);
                        return ERROR_OK;
                }
@@ -738,7 +739,7 @@ int evaluate_mul_and_extra_ld_st(u32 opcode, u32 address, arm_instruction_t *ins
        return evaluate_misc_load_store(opcode, address, instruction);
 }
 
-int evaluate_mrs_msr(u32 opcode, u32 address, arm_instruction_t *instruction)
+int evaluate_mrs_msr(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
 {
        int R = (opcode & 0x00400000) >> 22;
        char *PSR = (R) ? "SPSR" : "CPSR";
@@ -751,10 +752,10 @@ int evaluate_mrs_msr(u32 opcode, u32 address, arm_instruction_t *instruction)
                /* immediate variant */
                if (opcode & 0x02000000)
                {
-                       u8 immediate = (opcode & 0xff);
-                       u8 rotate = (opcode & 0xf00);
+                       uint8_t immediate = (opcode & 0xff);
+                       uint8_t rotate = (opcode & 0xf00);
                        
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tMSR%s %s_%s%s%s%s, 0x%8.8x",
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, 0x%8.8" PRIx32 ,
                                         address, opcode, COND(opcode), PSR,
                                         (opcode & 0x10000) ? "c" : "",
                                         (opcode & 0x20000) ? "x" : "",
@@ -765,8 +766,8 @@ int evaluate_mrs_msr(u32 opcode, u32 address, arm_instruction_t *instruction)
                }
                else /* register variant */
                {
-                       u8 Rm = opcode & 0xf;
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tMSR%s %s_%s%s%s%s, r%i",
+                       uint8_t Rm = opcode & 0xf;
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMSR%s %s_%s%s%s%s, r%i",
                                         address, opcode, COND(opcode), PSR,
                                         (opcode & 0x10000) ? "c" : "",
                                         (opcode & 0x20000) ? "x" : "",
@@ -779,12 +780,12 @@ int evaluate_mrs_msr(u32 opcode, u32 address, arm_instruction_t *instruction)
        }
        else /* Move status register to register (MRS) */
        {
-               u8 Rd;
+               uint8_t Rd;
                
                instruction->type = ARM_MRS;
                Rd = (opcode & 0x0000f000) >> 12;
                        
-               snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tMRS%s r%i, %s",
+               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tMRS%s r%i, %s",
                                 address, opcode, COND(opcode), Rd, PSR);
        }
        
@@ -792,7 +793,7 @@ int evaluate_mrs_msr(u32 opcode, u32 address, arm_instruction_t *instruction)
 }
 
 /* Miscellaneous instructions */
-int evaluate_misc_instr(u32 opcode, u32 address, arm_instruction_t *instruction)
+int evaluate_misc_instr(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
 {
        /* MRS/MSR */
        if ((opcode & 0x000000f0) == 0x00000000)
@@ -803,11 +804,11 @@ int evaluate_misc_instr(u32 opcode, u32 address, arm_instruction_t *instruction)
        /* BX */
        if ((opcode & 0x006000f0) == 0x00200010)
        {
-               u8 Rm;
+               uint8_t Rm;
                instruction->type = ARM_BX;
                Rm = opcode & 0xf;
                
-               snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tBX%s r%i",
+               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBX%s r%i",
                                 address, opcode, COND(opcode), Rm);
                
                instruction->info.b_bl_bx_blx.reg_operand = Rm;
@@ -815,32 +816,35 @@ int evaluate_misc_instr(u32 opcode, u32 address, arm_instruction_t *instruction)
        }
        
        /* CLZ */
-       if ((opcode & 0x0060000f0) == 0x00300010)
+       if ((opcode & 0x006000f0) == 0x00600010)
        {
-               u8 Rm, Rd;
+               uint8_t Rm, Rd;
                instruction->type = ARM_CLZ;
                Rm = opcode & 0xf;
                Rd = (opcode & 0xf000) >> 12;
 
-               snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tCLZ%s r%i, r%i",
+               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tCLZ%s r%i, r%i",
                                 address, opcode, COND(opcode), Rd, Rm);
        }
        
-       /* BLX */
-       if ((opcode & 0x0060000f0) == 0x00200030)
+       /* BLX(2) */
+       if ((opcode & 0x006000f0) == 0x00200030)
        {
-               u8 Rm;
+               uint8_t Rm;
                instruction->type = ARM_BLX;
                Rm = opcode & 0xf;
                
-               snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tBLX%s r%i",
+               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBLX%s r%i",
                                 address, opcode, COND(opcode), Rm);
+                                
+               instruction->info.b_bl_bx_blx.reg_operand = Rm;
+               instruction->info.b_bl_bx_blx.target_address = -1;
        }
        
        /* Enhanced DSP add/subtracts */
        if ((opcode & 0x0000000f0) == 0x00000050)
        {
-               u8 Rm, Rd, Rn;
+               uint8_t Rm, Rd, Rn;
                char *mnemonic = NULL;
                Rm = opcode & 0xf;
                Rd = (opcode & 0xf000) >> 12;
@@ -866,18 +870,18 @@ int evaluate_misc_instr(u32 opcode, u32 address, arm_instruction_t *instruction)
                                break;
                }
                
-               snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s r%i, r%i, r%i",
+               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, r%i, r%i",
                                 address, opcode, mnemonic, COND(opcode), Rd, Rm, Rn);
        }
        
        /* Software breakpoints */
        if ((opcode & 0x0000000f0) == 0x00000070)
        {
-               u32 immediate;
+               uint32_t immediate;
                instruction->type = ARM_BKPT;
                immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
                
-               snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tBKPT 0x%4.4x",
+               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBKPT 0x%4.4" PRIx32 "",
                                 address, opcode, immediate);   
        }
        
@@ -890,14 +894,14 @@ int evaluate_misc_instr(u32 opcode, u32 address, arm_instruction_t *instruction)
                /* SMLA<x><y> */
                if ((opcode & 0x00600000) == 0x00000000)
                {
-                       u8 Rd, Rm, Rs, Rn;
+                       uint8_t Rd, Rm, Rs, Rn;
                        instruction->type = ARM_SMLAxy;
                        Rd = (opcode & 0xf0000) >> 16;
                        Rm = (opcode & 0xf);
                        Rs = (opcode & 0xf00) >> 8;
                        Rn = (opcode & 0xf000) >> 12;
                        
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSMLA%s%s%s r%i, r%i, r%i, r%i",
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
                                         address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
                                         Rd, Rm, Rs, Rn);
                }
@@ -905,14 +909,14 @@ int evaluate_misc_instr(u32 opcode, u32 address, arm_instruction_t *instruction)
                /* SMLAL<x><y> */
                if ((opcode & 0x00600000) == 0x00400000)
                {
-                       u8 RdLow, RdHi, Rm, Rs;
+                       uint8_t RdLow, RdHi, Rm, Rs;
                        instruction->type = ARM_SMLAxy;
                        RdHi = (opcode & 0xf0000) >> 16;
                        RdLow = (opcode & 0xf000) >> 12;
                        Rm = (opcode & 0xf);
                        Rs = (opcode & 0xf00) >> 8;
                        
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSMLA%s%s%s r%i, r%i, r%i, r%i",
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLA%s%s%s r%i, r%i, r%i, r%i",
                                         address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
                                         RdLow, RdHi, Rm, Rs);
                }
@@ -920,14 +924,14 @@ int evaluate_misc_instr(u32 opcode, u32 address, arm_instruction_t *instruction)
                /* SMLAW<y> */
                if (((opcode & 0x00600000) == 0x00100000) && (x == 0))
                {
-                       u8 Rd, Rm, Rs, Rn;
+                       uint8_t Rd, Rm, Rs, Rn;
                        instruction->type = ARM_SMLAWy;
                        Rd = (opcode & 0xf0000) >> 16;
                        Rm = (opcode & 0xf);
                        Rs = (opcode & 0xf00) >> 8;
                        Rn = (opcode & 0xf000) >> 12;
 
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSMLAW%s%s r%i, r%i, r%i, r%i",
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMLAW%s%s r%i, r%i, r%i, r%i",
                                         address, opcode, (y) ? "T" : "B", COND(opcode),
                                         Rd, Rm, Rs, Rn);
                }
@@ -935,13 +939,13 @@ int evaluate_misc_instr(u32 opcode, u32 address, arm_instruction_t *instruction)
                /* SMUL<x><y> */
                if ((opcode & 0x00600000) == 0x00300000)
                {
-                       u8 Rd, Rm, Rs;
+                       uint8_t Rd, Rm, Rs;
                        instruction->type = ARM_SMULxy;
                        Rd = (opcode & 0xf0000) >> 16;
                        Rm = (opcode & 0xf);
                        Rs = (opcode & 0xf00) >> 8;
                        
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSMULW%s%s%s r%i, r%i, r%i",
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s%s r%i, r%i, r%i",
                                         address, opcode, (x) ? "T" : "B", (y) ? "T" : "B", COND(opcode),
                                         Rd, Rm, Rs);
                }
@@ -949,13 +953,13 @@ int evaluate_misc_instr(u32 opcode, u32 address, arm_instruction_t *instruction)
                /* SMULW<y> */
                if (((opcode & 0x00600000) == 0x00100000) && (x == 1))
                {
-                       u8 Rd, Rm, Rs;
+                       uint8_t Rd, Rm, Rs;
                        instruction->type = ARM_SMULWy;
                        Rd = (opcode & 0xf0000) >> 16;
                        Rm = (opcode & 0xf);
                        Rs = (opcode & 0xf00) >> 8;
                        
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tSMULW%s%s r%i, r%i, r%i",
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tSMULW%s%s r%i, r%i, r%i",
                                         address, opcode, (y) ? "T" : "B", COND(opcode),
                                         Rd, Rm, Rs);
                }
@@ -964,9 +968,9 @@ int evaluate_misc_instr(u32 opcode, u32 address, arm_instruction_t *instruction)
        return ERROR_OK;
 }
 
-int evaluate_data_proc(u32 opcode, u32 address, arm_instruction_t *instruction)
+int evaluate_data_proc(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
 {
-       u8 I, op, S, Rn, Rd;
+       uint8_t I, op, S, Rn, Rd;
        char *mnemonic = NULL;
        char shifter_operand[32];
        
@@ -1051,26 +1055,26 @@ int evaluate_data_proc(u32 opcode, u32 address, arm_instruction_t *instruction)
        
        if (I) /* immediate shifter operand (#<immediate>)*/
        {
-               u8 immed_8 = opcode & 0xff;
-               u8 rotate_imm = (opcode & 0xf00) >> 8;
-               u32 immediate;
+               uint8_t immed_8 = opcode & 0xff;
+               uint8_t rotate_imm = (opcode & 0xf00) >> 8;
+               uint32_t immediate;
                
                immediate = ror(immed_8, rotate_imm * 2);
                
-               snprintf(shifter_operand, 32, "#0x%x", immediate);
+               snprintf(shifter_operand, 32, "#0x%" PRIx32 "", immediate);
                
                instruction->info.data_proc.variant = 0;
                instruction->info.data_proc.shifter_operand.immediate.immediate = immediate;
        }
        else /* register-based shifter operand */
        {
-               u8 shift, Rm;
+               uint8_t shift, Rm;
                shift = (opcode & 0x60) >> 5;
                Rm = (opcode & 0xf);
                
                if ((opcode & 0x10) != 0x10) /* Immediate shifts ("<Rm>" or "<Rm>, <shift> #<shift_immediate>") */
                {
-                       u8 shift_imm;
+                       uint8_t shift_imm;
                        shift_imm = (opcode & 0xf80) >> 7;
 
                        instruction->info.data_proc.variant = 1;
@@ -1078,6 +1082,18 @@ int evaluate_data_proc(u32 opcode, u32 address, arm_instruction_t *instruction)
                        instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = shift_imm;
                        instruction->info.data_proc.shifter_operand.immediate_shift.shift = shift;
                
+                       /* LSR encodes a shift by 32 bit as 0x0 */
+                       if ((shift == 0x1) && (shift_imm == 0x0))
+                               shift_imm = 0x20;
+               
+                       /* ASR encodes a shift by 32 bit as 0x0 */
+                       if ((shift == 0x2) && (shift_imm == 0x0))
+                               shift_imm = 0x20;
+
+                       /* ROR by 32 bit is actually a RRX */
+                       if ((shift == 0x3) && (shift_imm == 0x0))
+                               shift = 0x4;
+                       
                        if ((shift_imm == 0x0) && (shift == 0x0))
                        {
                                snprintf(shifter_operand, 32, "r%i", Rm);
@@ -1090,28 +1106,25 @@ int evaluate_data_proc(u32 opcode, u32 address, arm_instruction_t *instruction)
                                }
                                else if (shift == 0x1) /* LSR */
                                {
-                                       if (shift_imm == 0x0)
-                                               shift_imm = 0x32;
                                        snprintf(shifter_operand, 32, "r%i, LSR #0x%x", Rm, shift_imm);
                                }
                                else if (shift == 0x2) /* ASR */
                                {
-                                       if (shift_imm == 0x0)
-                                               shift_imm = 0x32;
                                        snprintf(shifter_operand, 32, "r%i, ASR #0x%x", Rm, shift_imm);
                                }
-                               else if (shift == 0x3) /* ROR or RRX */
+                               else if (shift == 0x3) /* ROR */
                                {
-                                       if (shift_imm == 0x0) /* RRX */
-                                               snprintf(shifter_operand, 32, "r%i, RRX", Rm);
-                                       else
-                                               snprintf(shifter_operand, 32, "r%i, ROR #0x%x", Rm, shift_imm);
+                                       snprintf(shifter_operand, 32, "r%i, ROR #0x%x", Rm, shift_imm);
+                               }
+                               else if (shift == 0x4) /* RRX */
+                               {
+                                       snprintf(shifter_operand, 32, "r%i, RRX", Rm);
                                }
                        }
                }
                else /* Register shifts ("<Rm>, <shift> <Rs>") */
                {
-                       u8 Rs = (opcode & 0xf00) >> 8;
+                       uint8_t Rs = (opcode & 0xf00) >> 8;
                        
                        instruction->info.data_proc.variant = 2;
                        instruction->info.data_proc.shifter_operand.register_shift.Rm = Rm;
@@ -1130,7 +1143,7 @@ int evaluate_data_proc(u32 opcode, u32 address, arm_instruction_t *instruction)
                        {
                                snprintf(shifter_operand, 32, "r%i, ASR r%i", Rm, Rs);
                        }
-                       else if (shift == 0x3) /* ROR or RRX */
+                       else if (shift == 0x3) /* ROR */
                        {
                                snprintf(shifter_operand, 32, "r%i, ROR r%i", Rm, Rs);
                        }
@@ -1139,19 +1152,22 @@ int evaluate_data_proc(u32 opcode, u32 address, arm_instruction_t *instruction)
        
        if ((op < 0x8) || (op == 0xc) || (op == 0xe)) /* <opcode3>{<cond>}{S} <Rd>, <Rn>, <shifter_operand> */
        {
-               snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, r%i, %s",
+               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, r%i, %s",
                                 address, opcode, mnemonic, COND(opcode),
                                 (S) ? "S" : "", Rd, Rn, shifter_operand);
        }
        else if ((op == 0xd) || (op == 0xf)) /* <opcode1>{<cond>}{S} <Rd>, <shifter_operand> */
        {
-               snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s%s r%i, %s",
+               if (opcode==0xe1a00000) /* print MOV r0,r0 as NOP */
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tNOP",address, opcode);
+               else
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s%s r%i, %s",
                                 address, opcode, mnemonic, COND(opcode),
                                 (S) ? "S" : "", Rd, shifter_operand);
        }
        else /* <opcode2>{<cond>} <Rn>, <shifter_operand> */
        {
-               snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\t%s%s r%i, %s",
+               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s%s r%i, %s",
                                 address, opcode, mnemonic, COND(opcode),
                                 Rn, shifter_operand);
        }
@@ -1159,7 +1175,7 @@ int evaluate_data_proc(u32 opcode, u32 address, arm_instruction_t *instruction)
        return ERROR_OK;
 }
                
-int evaluate_opcode(u32 opcode, u32 address, arm_instruction_t *instruction)
+int arm_evaluate_opcode(uint32_t opcode, uint32_t address, arm_instruction_t *instruction)
 {
        /* clear fields, to avoid confusion */
        memset(instruction, 0, sizeof(arm_instruction_t));
@@ -1176,7 +1192,7 @@ int evaluate_opcode(u32 opcode, u32 address, arm_instruction_t *instruction)
                if ((opcode & 0x0e000000) == 0x08000000)
                {
                        instruction->type = ARM_UNDEFINED_INSTRUCTION;
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
                        return ERROR_OK;
                }
                
@@ -1201,7 +1217,7 @@ int evaluate_opcode(u32 opcode, u32 address, arm_instruction_t *instruction)
                if ((opcode & 0x0f000000) == 0x0f000000)
                {
                        instruction->type = ARM_UNDEFINED_INSTRUCTION;
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
                        return ERROR_OK;
                }
        }
@@ -1227,7 +1243,7 @@ int evaluate_opcode(u32 opcode, u32 address, arm_instruction_t *instruction)
                if ((opcode & 0x0fb00000) == 0x03000000)
                {
                        instruction->type = ARM_UNDEFINED_INSTRUCTION;
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
                        return ERROR_OK;
                }
                                
@@ -1253,7 +1269,7 @@ int evaluate_opcode(u32 opcode, u32 address, arm_instruction_t *instruction)
                if ((opcode & 0x00000010) == 0x00000010)
                {
                        instruction->type = ARM_UNDEFINED_INSTRUCTION;
-                       snprintf(instruction->text, 128, "0x%8.8x\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tUNDEFINED INSTRUCTION", address, opcode);
                        return ERROR_OK;
                }
                
@@ -1299,6 +1315,800 @@ int evaluate_opcode(u32 opcode, u32 address, arm_instruction_t *instruction)
                        return evaluate_cdp_mcr_mrc(opcode, address, instruction);
        }
        
-       ERROR("should never reach this point");
+       LOG_ERROR("should never reach this point");
+       return -1;
+}
+
+int evaluate_b_bl_blx_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
+{
+       uint32_t offset = opcode & 0x7ff;
+       uint32_t opc = (opcode >> 11) & 0x3;
+       uint32_t target_address;
+       char *mnemonic = NULL;
+       
+       /* sign extend 11-bit offset */
+       if (((opc==0) || (opc==2)) && (offset & 0x00000400))
+               offset = 0xfffff800 | offset;
+       
+       target_address = address + 4 + (offset << 1);
+
+       switch (opc)
+       {
+               /* unconditional branch */
+               case 0:
+                       instruction->type = ARM_B;
+                       mnemonic = "B";
+                       break;
+               /* BLX suffix */
+               case 1:
+                       instruction->type = ARM_BLX;
+                       mnemonic = "BLX";
+                       break;
+               /* BL/BLX prefix */
+               case 2:
+                       instruction->type = ARM_UNKNOWN_INSTUCTION;
+                       mnemonic = "prefix";
+                       target_address = offset << 12;
+                       break;
+               /* BL suffix */
+               case 3:
+                       instruction->type = ARM_BL;
+                       mnemonic = "BL";
+                       break;
+       }
+       /* TODO: deals correctly with dual opcodes BL/BLX ... */
+
+       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s 0x%8.8" PRIx32 , address, opcode,mnemonic, target_address);
+       
+       instruction->info.b_bl_bx_blx.reg_operand = -1;
+       instruction->info.b_bl_bx_blx.target_address = target_address;
+
+       return ERROR_OK;
+}
+
+int evaluate_add_sub_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
+{
+       uint8_t Rd = (opcode >> 0) & 0x7;
+       uint8_t Rn = (opcode >> 3) & 0x7;
+       uint8_t Rm_imm = (opcode >> 6) & 0x7;
+       uint32_t opc = opcode & (1 << 9);
+       uint32_t reg_imm  = opcode & (1 << 10);
+       char *mnemonic;
+       
+       if (opc)
+       {
+               instruction->type = ARM_SUB;
+               mnemonic = "SUBS";
+       }
+       else
+       {
+               instruction->type = ARM_ADD;
+               mnemonic = "ADDS";
+       }
+       
+       instruction->info.data_proc.Rd = Rd;
+       instruction->info.data_proc.Rn = Rn;
+       instruction->info.data_proc.S = 1;
+
+       if (reg_imm)
+       {
+               instruction->info.data_proc.variant = 0; /*immediate*/
+               instruction->info.data_proc.shifter_operand.immediate.immediate = Rm_imm;
+               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, r%i, #%d",
+                                address, opcode, mnemonic, Rd, Rn, Rm_imm);
+       }
+       else
+       {
+               instruction->info.data_proc.variant = 1; /*immediate shift*/
+               instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm_imm;
+               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, r%i, r%i",
+                                address, opcode, mnemonic, Rd, Rn, Rm_imm);
+       }
+
+       return ERROR_OK;
+}
+
+int evaluate_shift_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
+{
+       uint8_t Rd = (opcode >> 0) & 0x7;
+       uint8_t Rm = (opcode >> 3) & 0x7;
+       uint8_t imm = (opcode >> 6) & 0x1f;
+       uint8_t opc = (opcode >> 11) & 0x3;
+       char *mnemonic = NULL;
+       
+       switch (opc)
+       {
+               case 0:
+                       instruction->type = ARM_MOV;
+                       mnemonic = "LSLS";
+                       instruction->info.data_proc.shifter_operand.immediate_shift.shift = 0;
+                       break;
+               case 1:
+                       instruction->type = ARM_MOV;
+                       mnemonic = "LSRS";
+                       instruction->info.data_proc.shifter_operand.immediate_shift.shift = 1;
+                       break;
+               case 2:
+                       instruction->type = ARM_MOV;
+                       mnemonic = "ASRS";
+                       instruction->info.data_proc.shifter_operand.immediate_shift.shift = 2;
+                       break;
+       }
+
+       if ((imm==0) && (opc != 0))
+               imm = 32;
+
+       instruction->info.data_proc.Rd = Rd;
+       instruction->info.data_proc.Rn = -1;
+       instruction->info.data_proc.S = 1;
+
+       instruction->info.data_proc.variant = 1; /*immediate_shift*/
+       instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
+       instruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = imm;
+
+       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, r%i, #0x%02x" ,
+                                address, opcode, mnemonic, Rd, Rm, imm);
+
+       return ERROR_OK;
+}
+
+int evaluate_data_proc_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
+{
+       uint8_t imm = opcode & 0xff;
+       uint8_t Rd = (opcode >> 8) & 0x7;
+       uint32_t opc = (opcode >> 11) & 0x3;
+       char *mnemonic = NULL;
+       
+       instruction->info.data_proc.Rd = Rd;
+       instruction->info.data_proc.Rn = Rd;
+       instruction->info.data_proc.S = 1;
+       instruction->info.data_proc.variant = 0; /*immediate*/
+       instruction->info.data_proc.shifter_operand.immediate.immediate = imm;
+       
+       switch (opc)
+       {
+               case 0:
+                       instruction->type = ARM_MOV;
+                       mnemonic = "MOVS";
+                       instruction->info.data_proc.Rn = -1;
+                       break;
+               case 1:
+                       instruction->type = ARM_CMP;
+                       mnemonic = "CMP";
+                       instruction->info.data_proc.Rd = -1;
+                       break;
+               case 2:
+                       instruction->type = ARM_ADD;
+                       mnemonic = "ADDS";
+                       break;
+               case 3:
+                       instruction->type = ARM_SUB;
+                       mnemonic = "SUBS";
+                       break;
+       }
+       
+       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, #0x%02x" ,
+                                address, opcode, mnemonic, Rd, imm);
+
+       return ERROR_OK;
+}
+
+int evaluate_data_proc_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
+{
+       uint8_t high_reg, op, Rm, Rd,H1,H2;
+       char *mnemonic = NULL;
+       
+       high_reg = (opcode & 0x0400) >> 10;
+       op = (opcode & 0x03C0) >> 6;
+       
+       Rd = (opcode & 0x0007);
+       Rm = (opcode & 0x0038) >> 3;
+       H1 = (opcode & 0x0080) >> 7;
+       H2 = (opcode & 0x0040) >> 6;
+       
+       instruction->info.data_proc.Rd = Rd;
+       instruction->info.data_proc.Rn = Rd;
+       instruction->info.data_proc.S = (!high_reg || (instruction->type == ARM_CMP));
+       instruction->info.data_proc.variant = 1 /*immediate shift*/;
+       instruction->info.data_proc.shifter_operand.immediate_shift.Rm = Rm;
+
+       if (high_reg)
+       {
+               Rd |= H1 << 3;
+               Rm |= H2 << 3;
+               op >>= 2;
+       
+               switch (op)
+               {
+                       case 0x0:
+                               instruction->type = ARM_ADD;
+                               mnemonic = "ADD";
+                               break;
+                       case 0x1:
+                               instruction->type = ARM_CMP;
+                               mnemonic = "CMP";
+                               break;
+                       case 0x2:
+                               instruction->type = ARM_MOV;
+                               mnemonic = "MOV";
+                               break;
+                       case 0x3:
+                               if ((opcode & 0x7) == 0x0)
+                               {
+                                       instruction->info.b_bl_bx_blx.reg_operand = Rm;
+                                       if (H1)
+                                       {
+                                               instruction->type = ARM_BLX;
+                                               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tBLX r%i", address, opcode, Rm);
+                                       }
+                                       else
+                                       {
+                                               instruction->type = ARM_BX;
+                                               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tBX r%i", address, opcode, Rm);
+                                       }
+                               }
+                               else
+                               {
+                                       instruction->type = ARM_UNDEFINED_INSTRUCTION;
+                                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tUNDEFINED INSTRUCTION", address, opcode);
+                               }
+                               return ERROR_OK;        
+                               break;
+               }
+       }
+       else
+       {
+               switch (op)
+               {
+                       case 0x0:
+                               instruction->type = ARM_AND;
+                               mnemonic = "ANDS";
+                               break;
+                       case 0x1:
+                               instruction->type = ARM_EOR;
+                               mnemonic = "EORS";
+                               break;
+                       case 0x2:
+                               instruction->type = ARM_MOV;
+                               mnemonic = "LSLS";
+                               instruction->info.data_proc.variant = 2 /*register shift*/;
+                               instruction->info.data_proc.shifter_operand.register_shift.shift = 0;
+                               instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
+                               instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
+                               break;
+                       case 0x3:
+                               instruction->type = ARM_MOV;
+                               mnemonic = "LSRS";
+                               instruction->info.data_proc.variant = 2 /*register shift*/;
+                               instruction->info.data_proc.shifter_operand.register_shift.shift = 1;
+                               instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
+                               instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
+                               break;
+                       case 0x4:
+                               instruction->type = ARM_MOV;
+                               mnemonic = "ASRS";
+                               instruction->info.data_proc.variant = 2 /*register shift*/;
+                               instruction->info.data_proc.shifter_operand.register_shift.shift = 2;
+                               instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
+                               instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
+                               break;
+                       case 0x5:
+                               instruction->type = ARM_ADC;
+                               mnemonic = "ADCS";
+                               break;
+                       case 0x6:
+                               instruction->type = ARM_SBC;
+                               mnemonic = "SBCS";
+                               break;
+                       case 0x7:
+                               instruction->type = ARM_MOV;
+                               mnemonic = "RORS";
+                               instruction->info.data_proc.variant = 2 /*register shift*/;
+                               instruction->info.data_proc.shifter_operand.register_shift.shift = 3;
+                               instruction->info.data_proc.shifter_operand.register_shift.Rm = Rd;
+                               instruction->info.data_proc.shifter_operand.register_shift.Rs = Rm;
+                               break;
+                       case 0x8:
+                               instruction->type = ARM_TST;
+                               mnemonic = "TST";
+                               break;
+                       case 0x9:
+                               instruction->type = ARM_RSB;
+                               mnemonic = "NEGS";
+                               instruction->info.data_proc.variant = 0 /*immediate*/;
+                               instruction->info.data_proc.shifter_operand.immediate.immediate = 0;
+                               instruction->info.data_proc.Rn = Rm;
+                               break;
+                       case 0xA:
+                               instruction->type = ARM_CMP;
+                               mnemonic = "CMP";
+                               break;
+                       case 0xB:
+                               instruction->type = ARM_CMN;
+                               mnemonic = "CMN";
+                               break;
+                       case 0xC:
+                               instruction->type = ARM_ORR;
+                               mnemonic = "ORRS";
+                               break;
+                       case 0xD:
+                               instruction->type = ARM_MUL;
+                               mnemonic = "MULS";
+                               break;
+                       case 0xE:
+                               instruction->type = ARM_BIC;
+                               mnemonic = "BICS";
+                               break;
+                       case 0xF:
+                               instruction->type = ARM_MVN;
+                               mnemonic = "MVNS";
+                               break;
+               }
+       }
+
+       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, r%i",
+                                address, opcode, mnemonic, Rd, Rm);
+
+       return ERROR_OK;
+}
+
+int evaluate_load_literal_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
+{
+       uint32_t immediate;
+       uint8_t Rd = (opcode >> 8) & 0x7; 
+
+       instruction->type = ARM_LDR;
+       immediate = opcode & 0x000000ff;
+
+       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tLDR r%i, [PC, #0x%" PRIx32 "]", address, opcode, Rd, immediate*4);
+
+       instruction->info.load_store.Rd = Rd;
+       instruction->info.load_store.Rn = 15 /*PC*/;
+       instruction->info.load_store.index_mode = 0; /*offset*/
+       instruction->info.load_store.offset_mode = 0; /*immediate*/
+       instruction->info.load_store.offset.offset = immediate*4;
+
+       return ERROR_OK;
+}
+
+int evaluate_load_store_reg_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
+{
+       uint8_t Rd = (opcode >> 0) & 0x7; 
+       uint8_t Rn = (opcode >> 3) & 0x7; 
+       uint8_t Rm = (opcode >> 6) & 0x7; 
+       uint8_t opc = (opcode >> 9) & 0x7; 
+       char *mnemonic = NULL;
+
+       switch (opc)
+       {
+               case 0:
+                       instruction->type = ARM_STR;
+                       mnemonic = "STR";
+                       break;
+               case 1:
+                       instruction->type = ARM_STRH;
+                       mnemonic = "STRH";
+                       break;
+               case 2:
+                       instruction->type = ARM_STRB;
+                       mnemonic = "STRB";
+                       break;
+               case 3:
+                       instruction->type = ARM_LDRSB;
+                       mnemonic = "LDRSB";
+                       break;
+               case 4:
+                       instruction->type = ARM_LDR;
+                       mnemonic = "LDR";
+                       break;
+               case 5:
+                       instruction->type = ARM_LDRH;
+                       mnemonic = "LDRH";
+                       break;
+               case 6:
+                       instruction->type = ARM_LDRB;
+                       mnemonic = "LDRB";
+                       break;
+               case 7:
+                       instruction->type = ARM_LDRSH;
+                       mnemonic = "LDRSH";
+                       break;
+       }
+
+       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, [r%i, r%i]", address, opcode, mnemonic, Rd, Rn, Rm);
+       
+       instruction->info.load_store.Rd = Rd;
+       instruction->info.load_store.Rn = Rn;
+       instruction->info.load_store.index_mode = 0; /*offset*/
+       instruction->info.load_store.offset_mode = 1; /*register*/
+       instruction->info.load_store.offset.reg.Rm = Rm;
+
+       return ERROR_OK;
+}
+
+int evaluate_load_store_imm_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
+{
+       uint32_t offset = (opcode >> 6) & 0x1f;
+       uint8_t Rd = (opcode >> 0) & 0x7; 
+       uint8_t Rn = (opcode >> 3) & 0x7; 
+       uint32_t L = opcode & (1 << 11);
+       uint32_t B = opcode & (1 << 12);
+       char *mnemonic;
+       char suffix = ' ';
+       uint32_t shift = 2;
+
+       if (L)
+       {
+               instruction->type = ARM_LDR;
+               mnemonic = "LDR";
+       }
+       else
+       {
+               instruction->type = ARM_STR;
+               mnemonic = "STR";
+       }
+
+       if ((opcode&0xF000)==0x8000)
+       {
+               suffix = 'H';
+               shift = 1;
+       }
+       else if (B)
+       {
+               suffix = 'B';
+               shift = 0;
+       }
+
+       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s%c r%i, [r%i, #0x%" PRIx32 "]", address, opcode, mnemonic, suffix, Rd, Rn, offset << shift);
+       
+       instruction->info.load_store.Rd = Rd;
+       instruction->info.load_store.Rn = Rn;
+       instruction->info.load_store.index_mode = 0; /*offset*/
+       instruction->info.load_store.offset_mode = 0; /*immediate*/
+       instruction->info.load_store.offset.offset = offset << shift;
+
+       return ERROR_OK;
+}
+
+int evaluate_load_store_stack_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
+{
+       uint32_t offset = opcode  & 0xff;
+       uint8_t Rd = (opcode >> 8) & 0x7; 
+       uint32_t L = opcode & (1 << 11);
+       char *mnemonic;
+
+       if (L)
+       {
+               instruction->type = ARM_LDR;
+               mnemonic = "LDR";
+       }
+       else
+       {
+               instruction->type = ARM_STR;
+               mnemonic = "STR";
+       }
+
+       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s r%i, [SP, #0x%" PRIx32 "]", address, opcode, mnemonic, Rd, offset*4);
+       
+       instruction->info.load_store.Rd = Rd;
+       instruction->info.load_store.Rn = 13 /*SP*/;
+       instruction->info.load_store.index_mode = 0; /*offset*/
+       instruction->info.load_store.offset_mode = 0; /*immediate*/
+       instruction->info.load_store.offset.offset = offset*4;
+
+       return ERROR_OK;
+}
+
+int evaluate_add_sp_pc_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
+{
+       uint32_t imm = opcode  & 0xff;
+       uint8_t Rd = (opcode >> 8) & 0x7; 
+       uint8_t Rn;
+       uint32_t SP = opcode & (1 << 11);
+       char *reg_name;
+
+       instruction->type = ARM_ADD;
+       
+       if (SP)
+       {
+               reg_name = "SP";
+               Rn = 13;
+       }
+       else
+       {
+               reg_name = "PC";
+               Rn = 15;
+       }
+
+       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tADD r%i, %s, #0x%" PRIx32 "", address, opcode, Rd,reg_name, imm*4);
+
+       instruction->info.data_proc.variant = 0 /* immediate */;
+       instruction->info.data_proc.Rd = Rd;
+       instruction->info.data_proc.Rn = Rn;
+       instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
+
+       return ERROR_OK;
+}
+
+int evaluate_adjust_stack_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
+{
+       uint32_t imm = opcode  & 0x7f;
+       uint8_t opc = opcode & (1 << 7);
+       char *mnemonic;
+
+       
+       if (opc)
+       {
+               instruction->type = ARM_SUB;
+               mnemonic = "SUB";
+       }
+       else
+       {
+               instruction->type = ARM_ADD;
+               mnemonic = "ADD";
+       }
+
+       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s SP, #0x%" PRIx32 "", address, opcode, mnemonic, imm*4);
+
+       instruction->info.data_proc.variant = 0 /* immediate */;
+       instruction->info.data_proc.Rd = 13 /*SP*/;
+       instruction->info.data_proc.Rn = 13 /*SP*/;
+       instruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;
+
+       return ERROR_OK;
+}
+
+int evaluate_breakpoint_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
+{
+       uint32_t imm = opcode  & 0xff;
+       
+       instruction->type = ARM_BKPT;
+
+       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tBKPT 0x%02" PRIx32 "", address, opcode, imm);
+
+       return ERROR_OK;
+}
+
+int evaluate_load_store_multiple_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
+{
+       uint32_t reg_list = opcode  & 0xff;
+       uint32_t L = opcode & (1 << 11);
+       uint32_t R = opcode & (1 << 8);
+       uint8_t Rn = (opcode >> 8) & 7;
+       uint8_t addr_mode = 0 /* IA */;
+       char reg_names[40];
+       char *reg_names_p;
+       char *mnemonic;
+       char ptr_name[7] = "";
+       int i;  
+
+       if ((opcode & 0xf000) == 0xc000)
+       { /* generic load/store multiple */
+               if (L)
+               {
+                       instruction->type = ARM_LDM;
+                       mnemonic = "LDMIA";
+               }
+               else
+               {
+                       instruction->type = ARM_STM;
+                       mnemonic = "STMIA";
+               }
+               snprintf(ptr_name,7,"r%i!, ",Rn);
+       }
+       else
+       { /* push/pop */
+               Rn = 13; /* SP */
+               if (L)
+               {
+                       instruction->type = ARM_LDM;
+                       mnemonic = "POP";
+                       if (R)
+                               reg_list |= (1 << 15) /*PC*/;
+               }
+               else
+               {
+                       instruction->type = ARM_STM;
+                       mnemonic = "PUSH";
+                       addr_mode = 3; /*DB*/
+                       if (R)
+                               reg_list |= (1 << 14) /*LR*/;
+               }
+       }
+
+       reg_names_p = reg_names;
+       for (i = 0; i <= 15; i++)
+       {
+               if (reg_list & (1 << i))
+                       reg_names_p += snprintf(reg_names_p, (reg_names + 40 - reg_names_p), "r%i, ", i);
+       }
+       if (reg_names_p>reg_names)
+               reg_names_p[-2] = '\0';
+       else /* invalid op : no registers */
+               reg_names[0] = '\0';
+
+       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\t%s %s{%s}", address, opcode, mnemonic, ptr_name,reg_names);
+
+       instruction->info.load_store_multiple.register_list = reg_list;
+       instruction->info.load_store_multiple.Rn = Rn;
+       instruction->info.load_store_multiple.addressing_mode = addr_mode;
+
+       return ERROR_OK;
+}
+
+int evaluate_cond_branch_thumb(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
+{
+       uint32_t offset = opcode  & 0xff;
+       uint8_t cond = (opcode >> 8) & 0xf;
+       uint32_t target_address;
+
+       if (cond == 0xf)
+       {
+               instruction->type = ARM_SWI;
+               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tSWI 0x%02" PRIx32 , address, opcode, offset);
+               return ERROR_OK;
+       }
+       else if (cond == 0xe)
+       {
+               instruction->type = ARM_UNDEFINED_INSTRUCTION;
+               snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tUNDEFINED INSTRUCTION", address, opcode);
+               return ERROR_OK;
+       }
+
+       /* sign extend 8-bit offset */
+       if (offset & 0x00000080)
+               offset = 0xffffff00 | offset;
+       
+       target_address = address + 4 + (offset << 1);
+
+       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tB%s 0x%8.8" PRIx32 , address, opcode,
+                        arm_condition_strings[cond], target_address);
+       
+       instruction->type = ARM_B;
+       instruction->info.b_bl_bx_blx.reg_operand = -1;
+       instruction->info.b_bl_bx_blx.target_address = target_address;
+
+       return ERROR_OK;
+}
+
+int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, arm_instruction_t *instruction)
+{
+       /* clear fields, to avoid confusion */
+       memset(instruction, 0, sizeof(arm_instruction_t));
+       instruction->opcode = opcode;
+       
+       if ((opcode & 0xe000) == 0x0000)
+       {
+               /* add/substract register or immediate */
+               if ((opcode & 0x1800) == 0x1800)
+                       return evaluate_add_sub_thumb(opcode, address, instruction);
+               /* shift by immediate */
+               else
+                       return evaluate_shift_imm_thumb(opcode, address, instruction);
+       }
+       
+       /* Add/substract/compare/move immediate */
+       if ((opcode & 0xe000) == 0x2000)
+       {
+               return evaluate_data_proc_imm_thumb(opcode, address, instruction);
+       }
+       
+       /* Data processing instructions */
+       if ((opcode & 0xf800) == 0x4000)
+       {
+               return evaluate_data_proc_thumb(opcode, address, instruction);
+       }
+       
+       /* Load from literal pool */
+       if ((opcode & 0xf800) == 0x4800)
+       {
+               return evaluate_load_literal_thumb(opcode, address, instruction);
+       }
+
+       /* Load/Store register offset */
+       if ((opcode & 0xf000) == 0x5000)
+       {
+               return evaluate_load_store_reg_thumb(opcode, address, instruction);
+       }
+
+       /* Load/Store immediate offset */
+       if (((opcode & 0xe000) == 0x6000)
+               ||((opcode & 0xf000) == 0x8000))
+       {
+               return evaluate_load_store_imm_thumb(opcode, address, instruction);
+       }
+       
+       /* Load/Store from/to stack */
+       if ((opcode & 0xf000) == 0x9000)
+       {
+               return evaluate_load_store_stack_thumb(opcode, address, instruction);
+       }
+
+       /* Add to SP/PC */
+       if ((opcode & 0xf000) == 0xa000)
+       {
+               return evaluate_add_sp_pc_thumb(opcode, address, instruction);
+       }
+
+       /* Misc */
+       if ((opcode & 0xf000) == 0xb000)
+       {
+               if ((opcode & 0x0f00) == 0x0000)
+                       return evaluate_adjust_stack_thumb(opcode, address, instruction);
+               else if ((opcode & 0x0f00) == 0x0e00)
+                       return evaluate_breakpoint_thumb(opcode, address, instruction);
+               else if ((opcode & 0x0600) == 0x0400) /* push pop */
+                       return evaluate_load_store_multiple_thumb(opcode, address, instruction);
+               else
+               {
+                       instruction->type = ARM_UNDEFINED_INSTRUCTION;
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%4.4x\tUNDEFINED INSTRUCTION", address, opcode);
+                       return ERROR_OK;
+               }
+       }
+
+       /* Load/Store multiple */
+       if ((opcode & 0xf000) == 0xc000)
+       {
+               return evaluate_load_store_multiple_thumb(opcode, address, instruction);
+       }
+
+       /* Conditional branch + SWI */
+       if ((opcode & 0xf000) == 0xd000)
+       {
+               return evaluate_cond_branch_thumb(opcode, address, instruction);
+       }
+       
+       if ((opcode & 0xe000) == 0xe000)
+       {
+               /* Undefined instructions */
+               if ((opcode & 0xf801) == 0xe801)
+               {
+                       instruction->type = ARM_UNDEFINED_INSTRUCTION;
+                       snprintf(instruction->text, 128, "0x%8.8" PRIx32 "\t0x%8.8x\tUNDEFINED INSTRUCTION", address, opcode);
+                       return ERROR_OK;
+               }
+               else
+               { /* Branch to offset */
+                       return evaluate_b_bl_blx_thumb(opcode, address, instruction);
+               }
+       }
+
+       LOG_ERROR("should never reach this point (opcode=%04x)",opcode);
        return -1;
 }
+
+int arm_access_size(arm_instruction_t *instruction)
+{
+       if ((instruction->type == ARM_LDRB)
+               || (instruction->type == ARM_LDRBT)
+               || (instruction->type == ARM_LDRSB)
+               || (instruction->type == ARM_STRB)
+               || (instruction->type == ARM_STRBT))
+       {
+               return 1;
+       }
+       else if ((instruction->type == ARM_LDRH)
+               || (instruction->type == ARM_LDRSH)
+               || (instruction->type == ARM_STRH))
+       {
+               return 2;
+       }
+       else if ((instruction->type == ARM_LDR)
+               || (instruction->type == ARM_LDRT)
+               || (instruction->type == ARM_STR)
+               || (instruction->type == ARM_STRT))
+       {
+               return 4;
+       }
+       else if ((instruction->type == ARM_LDRD)
+               || (instruction->type == ARM_STRD))
+       {
+               return 8;
+       }
+       else
+       {
+               LOG_ERROR("BUG: instruction type %i isn't a load/store instruction", instruction->type);
+               return 0;
+       }
+}

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)