Fix "unused variable" warnings (errors) detected with GCC 4.7.0 - trivial fixes
[fw/openocd] / src / target / arm_disassembler.c
index b93df64d10b2f5fd8a8824c06f1909f2e4a0ef2d..36566c9932ec725a52814100e1fbfceb5429cdec 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "target.h"
 #include "arm_disassembler.h"
-#include "log.h"
+#include <helper/log.h>
 
 
 /*
@@ -50,6 +50,7 @@
  *       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
@@ -106,6 +107,16 @@ static uint32_t ror(uint32_t value, int places)
        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, struct arm_instruction *instruction)
 {
@@ -118,14 +129,51 @@ static int evaluate_pld(uint32_t opcode,
 
                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,
@@ -241,19 +289,24 @@ static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode,
                        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 */
        {
                uint8_t CRd, Rn, offset;
-               uint8_t U, N;
+               uint8_t U;
                char *mnemonic;
                char addressing_mode[32];
 
                CRd = (opcode & 0xf000) >> 12;
                Rn = (opcode & 0xf0000) >> 16;
-               offset = (opcode & 0xff);
+               offset = (opcode & 0xff) << 2;
 
                /* load/store */
                if (opcode & 0x00100000)
@@ -268,22 +321,29 @@ static int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode,
                }
 
                U = (opcode & 0x00800000) >> 23;
-               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;
@@ -1037,8 +1097,11 @@ static int evaluate_ldm_stm(uint32_t opcode,
                }
        }
 
-       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;
@@ -1591,7 +1654,8 @@ static int evaluate_data_proc(uint32_t opcode,
        return ERROR_OK;
 }
 
-int arm_evaluate_opcode(uint32_t opcode, uint32_t address, struct arm_instruction *instruction)
+int arm_evaluate_opcode(uint32_t opcode, uint32_t address,
+               struct arm_instruction *instruction)
 {
        /* clear fields, to avoid confusion */
        memset(instruction, 0, sizeof(struct arm_instruction));
@@ -1605,13 +1669,9 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, struct arm_instructio
                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)
@@ -1717,7 +1777,7 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, struct arm_instructio
        }
 
        /* 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);
@@ -1739,7 +1799,8 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address, struct arm_instructio
                        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;
 }
 
@@ -2292,7 +2353,7 @@ static int evaluate_add_sp_pc_thumb(uint16_t opcode,
        uint8_t Rd = (opcode >> 8) & 0x7;
        uint8_t Rn;
        uint32_t SP = opcode & (1 << 11);
-       char *reg_name;
+       const char *reg_name;
 
        instruction->type = ARM_ADD;
 
@@ -2753,7 +2814,7 @@ int thumb_evaluate_opcode(uint16_t opcode, uint32_t address, struct arm_instruct
                }
        }
 
-       LOG_ERROR("should never reach this point (opcode=%04x)",opcode);
+       LOG_ERROR("Thumb: should never reach this point (opcode=%04x)", opcode);
        return -1;
 }
 
@@ -3186,7 +3247,7 @@ static int t2ev_data_immed(uint32_t opcode, uint32_t address,
        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:
@@ -3414,11 +3475,28 @@ static int t2ev_ldm_stm(uint32_t opcode, uint32_t address,
        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;