* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
return ERROR_OK;
}
+ /* DSB */
+ if ((opcode & 0x07f000f0) == 0x05700040) {
+ instruction->type = ARM_DSB;
+
+ char *opt;
+ switch (opcode & 0x0000000f) {
+ case 0xf:
+ opt = "SY";
+ break;
+ case 0xe:
+ opt = "ST";
+ break;
+ case 0xb:
+ opt = "ISH";
+ break;
+ case 0xa:
+ opt = "ISHST";
+ break;
+ case 0x7:
+ opt = "NSH";
+ break;
+ case 0x6:
+ opt = "NSHST";
+ break;
+ case 0x3:
+ opt = "OSH";
+ break;
+ case 0x2:
+ opt = "OSHST";
+ break;
+ default:
+ opt = "UNK";
+ }
+
+ snprintf(instruction->text,
+ 128,
+ "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tDSB %s",
+ address, opcode, opt);
+
+ return ERROR_OK;
+ }
return evaluate_unknown(opcode, address, instruction);
}
uint8_t cp_num = (opcode & 0xf00) >> 8;
/* MCRR or MRRC */
- if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c400000)) {
+ if (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c500000)) {
uint8_t cp_opcode, Rd, Rn, CRm;
char *mnemonic;
Rn);
}
- /* Software breakpoints */
+ /* exception return */
+ if ((opcode & 0x0000000f0) == 0x00000060) {
+ if (((opcode & 0x600000) >> 21) == 3)
+ instruction->type = ARM_ERET;
+ snprintf(instruction->text,
+ 128,
+ "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tERET",
+ address,
+ opcode);
+ }
+
+ /* exception generate instructions */
if ((opcode & 0x0000000f0) == 0x00000070) {
- uint32_t immediate;
- instruction->type = ARM_BKPT;
- immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
+ uint32_t immediate = 0;
+ char *mnemonic = NULL;
+
+ switch ((opcode & 0x600000) >> 21) {
+ case 0x1:
+ instruction->type = ARM_BKPT;
+ mnemonic = "BRKT";
+ immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
+ break;
+ case 0x2:
+ instruction->type = ARM_HVC;
+ mnemonic = "HVC";
+ immediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);
+ break;
+ case 0x3:
+ instruction->type = ARM_SMC;
+ mnemonic = "SMC";
+ immediate = (opcode & 0xf);
+ break;
+ }
snprintf(instruction->text,
128,
- "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\tBKPT 0x%4.4" PRIx32 "",
+ "0x%8.8" PRIx32 "\t0x%8.8" PRIx32 "\t%s 0x%4.4" PRIx32 "",
address,
opcode,
+ mnemonic,
immediate);
}
address += 4;
address += offset << 1;
- instruction->type = (opcode & (1 << 14)) ? ARM_BL : ARM_B;
+ char *inst;
+ switch ((opcode >> 12) & 0x5) {
+ case 0x1:
+ inst = "B.W";
+ instruction->type = ARM_B;
+ break;
+ case 0x4:
+ inst = "BLX";
+ instruction->type = ARM_BLX;
+ break;
+ case 0x5:
+ inst = "BL";
+ instruction->type = ARM_BL;
+ break;
+ default:
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
instruction->info.b_bl_bx_blx.reg_operand = -1;
instruction->info.b_bl_bx_blx.target_address = address;
- sprintf(cp, "%s\t%#8.8" PRIx32,
- (opcode & (1 << 14)) ? "BL" : "B.W",
- address);
+ sprintf(cp, "%s\t%#8.8" PRIx32, inst, address);
return ERROR_OK;
}
switch ((opcode >> 12) & 0x5) {
case 0x1:
+ case 0x4:
case 0x5:
return t2ev_b_bl(opcode, address, instruction, cp);
- case 0x4:
- goto undef;
case 0:
if (((opcode >> 23) & 0x07) != 0x07)
return t2ev_cond_b(opcode, address, instruction, cp);
case 0x10:
case 0x12:
is_signed = true;
+ /* fallthrough */
case 0x18:
case 0x1a:
/* signed/unsigned saturated add */