* 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
{
instruction->type = ARM_MCRR;
mnemonic = "MCRR";
- }
-
- /* MRRC */
- if ((opcode & 0x0ff00000) == 0x0c500000)
- {
+ } else if ((opcode & 0x0ff00000) == 0x0c500000) {
+ /* MRRC */
instruction->type = ARM_MRRC;
mnemonic = "MRRC";
+ } else {
+ LOG_ERROR("Unknown instruction");
+ return ERROR_FAIL;
}
snprintf(instruction->text, 128,
else /* LDC or STC */
{
uint8_t CRd, Rn, offset;
- uint8_t U, N;
+ uint8_t U;
char *mnemonic;
char addressing_mode[32];
}
U = (opcode & 0x00800000) >> 23;
- N = (opcode & 0x00400000) >> 22;
/* addressing modes */
if ((opcode & 0x01200000) == 0x01000000) /* offset */
}
}
- 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;
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;
mnemonic = "ISB";
break;
default:
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
strcpy(cp, mnemonic);
return ERROR_OK;
}
undef:
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
static int t2ev_data_mod_immed(uint32_t opcode, uint32_t address,
suffix2 = ".W";
break;
default:
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
if (one)
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:
(int) (opcode & 0x1f) + 1 - immed);
return ERROR_OK;
default:
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
sprintf(cp, "%s\tr%d, r%d, #%d\t; %#3.3x", mnemonic,
unsigned rt = (opcode >> 12) & 0x0f;
if (rn == 0xf)
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
if (opcode & 0x0800)
op |= 1;
break;
/* error */
default:
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
sprintf(cp, "STR%s.W\tr%d, [r%d, r%d, LSL #%d]",
break;
case 0x000:
case 0x200:
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
/* two indexed modes will write back rn */
(int) (opcode >> 0) & 0xf, ra);
break;
default:
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
return ERROR_OK;
}
(int) (opcode >> 0) & 0xf);
break;
default:
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
return ERROR_OK;
sprintf(cp, "LDMDB.W\tr%d%s, ", rn, t ? "!" : "");
break;
default:
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
cp = strchr(cp, 0);
mnemonic = "STREXH";
break;
default:
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
rd = opcode & 0xf;
imm = 0;
mnemonic = "LDREXH";
break;
default:
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
imm = 0;
goto ldrex;
}
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
strex:
imm <<= 2;
case 0:
if (rd == 0xf) {
if (!(opcode & (1 << 20)))
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
instruction->type = ARM_TST;
mnemonic = "TST";
suffix = "";
case 4:
if (rd == 0xf) {
if (!(opcode & (1 << 20)))
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
instruction->type = ARM_TEQ;
mnemonic = "TEQ";
suffix = "";
case 8:
if (rd == 0xf) {
if (!(opcode & (1 << 20)))
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
instruction->type = ARM_CMN;
mnemonic = "CMN";
suffix = "";
case 0xd:
if (rd == 0xf) {
if (!(opcode & (1 << 21)))
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
instruction->type = ARM_CMP;
mnemonic = "CMP";
suffix = "";
mnemonic = "RSB";
break;
default:
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
sprintf(cp, "%s%s.W\tr%d, r%d, r%d",
mnemonic = "ROR";
break;
default:
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
instruction->type = ARM_MOV;
case 0xa:
case 0xb:
if (opcode & (1 << 6))
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
if (((opcode >> 12) & 0xf) != 0xf)
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
if (!(opcode & (1 << 20)))
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
switch (((opcode >> 19) & 0x04)
| ((opcode >> 4) & 0x3)) {
mnemonic = "CLZ";
break;
default:
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
sprintf(cp, "%s\tr%d, r%d",
mnemonic,
(int) (opcode >> 0) & 0xf);
break;
default:
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
}
char *p1 = "]", *p2 = "";
if (!(opcode & 0x0500))
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
immed = opcode & 0x00ff;
return ERROR_OK;
}
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
static int t2ev_load_byte_hints(uint32_t opcode, uint32_t address,
goto ldrxb_immediate_t2;
}
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
static int t2ev_load_halfword(uint32_t opcode, uint32_t address,
return ERROR_OK;
}
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
/*
* instructions; not yet handled here.
*/
- if (retval == ERROR_INVALID_ARGUMENTS) {
+ if (retval == ERROR_COMMAND_SYNTAX_ERROR) {
instruction->type = ARM_UNDEFINED_INSTRUCTION;
strcpy(cp, "UNDEFINED OPCODE");
return ERROR_OK;