dis: alter interface to allow for MSP430X instruction set.
This commit is contained in:
parent
636e11b626
commit
8846186979
|
@ -127,13 +127,18 @@ static int dis_format(stab_t stab, char *buf, int max_len,
|
|||
int tlen;
|
||||
int total = 0;
|
||||
const char *opname = dis_opcode_name(insn->op);
|
||||
const char *suffix = "";
|
||||
|
||||
if (!opname)
|
||||
opname = "???";
|
||||
|
||||
if (insn->dsize == MSP430_DSIZE_BYTE)
|
||||
suffix = ".B";
|
||||
else if (insn->dsize == MSP430_DSIZE_AWORD)
|
||||
suffix = ".A";
|
||||
|
||||
len = snprintf(buf + total, max_len - total,
|
||||
"\x1b[36m%s%s\x1b[0m", opname,
|
||||
insn->is_byte_op ? ".B" : "");
|
||||
"\x1b[36m%s%s\x1b[0m", opname, suffix);
|
||||
tlen = textlen(buf + total);
|
||||
total += len;
|
||||
|
||||
|
|
40
dis.c
40
dis.c
|
@ -25,6 +25,8 @@
|
|||
#include "dis.h"
|
||||
#include "util.h"
|
||||
|
||||
#define ALL_ONES 0xfffff
|
||||
|
||||
/**********************************************************************/
|
||||
/* Disassembler
|
||||
*/
|
||||
|
@ -34,14 +36,14 @@
|
|||
* Returns the number of bytes consumed in decoding, or -1 if the a
|
||||
* valid single-operand instruction could not be found.
|
||||
*/
|
||||
static int decode_single(const uint8_t *code, uint16_t offset,
|
||||
uint16_t size, struct msp430_instruction *insn)
|
||||
static int decode_single(const uint8_t *code, address_t offset,
|
||||
address_t size, struct msp430_instruction *insn)
|
||||
{
|
||||
uint16_t op = (code[1] << 8) | code[0];
|
||||
int need_arg = 0;
|
||||
|
||||
insn->op = op & 0xff80;
|
||||
insn->is_byte_op = op & 0x0400;
|
||||
insn->dsize = (op & 0x0400) ? MSP430_DSIZE_BYTE : MSP430_DSIZE_WORD;
|
||||
|
||||
insn->dst_mode = (op >> 4) & 0x3;
|
||||
insn->dst_reg = op & 0xf;
|
||||
|
@ -86,8 +88,8 @@ static int decode_single(const uint8_t *code, uint16_t offset,
|
|||
* Returns the number of bytes consumed or -1 if a valid instruction
|
||||
* could not be found.
|
||||
*/
|
||||
static int decode_double(const uint8_t *code, uint16_t offset,
|
||||
uint16_t size, struct msp430_instruction *insn)
|
||||
static int decode_double(const uint8_t *code, address_t offset,
|
||||
address_t size, struct msp430_instruction *insn)
|
||||
{
|
||||
uint16_t op = (code[1] << 8) | code[0];
|
||||
int need_src = 0;
|
||||
|
@ -95,7 +97,7 @@ static int decode_double(const uint8_t *code, uint16_t offset,
|
|||
int ret = 2;
|
||||
|
||||
insn->op = op & 0xf000;
|
||||
insn->is_byte_op = op & 0x0040;
|
||||
insn->dsize = (op & 0x0040) ? MSP430_DSIZE_BYTE : MSP430_DSIZE_WORD;
|
||||
|
||||
insn->src_mode = (op >> 4) & 0x3;
|
||||
insn->src_reg = (op >> 8) & 0xf;
|
||||
|
@ -175,7 +177,7 @@ static int decode_double(const uint8_t *code, uint16_t offset,
|
|||
* All jump instructions are one word in length, so this function
|
||||
* always returns 2 (to indicate the consumption of 2 bytes).
|
||||
*/
|
||||
static int decode_jump(const uint8_t *code, uint16_t offset, uint16_t len,
|
||||
static int decode_jump(const uint8_t *code, address_t offset, address_t len,
|
||||
struct msp430_instruction *insn)
|
||||
{
|
||||
uint16_t op = (code[1] << 8) | code[0];
|
||||
|
@ -193,7 +195,7 @@ static int decode_jump(const uint8_t *code, uint16_t offset, uint16_t len,
|
|||
}
|
||||
|
||||
static void remap_cgen(msp430_amode_t *mode,
|
||||
uint16_t *addr,
|
||||
address_t *addr,
|
||||
msp430_reg_t *reg)
|
||||
{
|
||||
if (*reg == MSP430_REG_SR) {
|
||||
|
@ -212,7 +214,7 @@ static void remap_cgen(msp430_amode_t *mode,
|
|||
else if (*mode == MSP430_AMODE_INDIRECT)
|
||||
*addr = 2;
|
||||
else if (*mode == MSP430_AMODE_INDIRECT_INC)
|
||||
*addr = 0xffff;
|
||||
*addr = ALL_ONES;
|
||||
|
||||
*mode = MSP430_AMODE_IMMEDIATE;
|
||||
}
|
||||
|
@ -377,7 +379,7 @@ static void find_emulated_ops(struct msp430_instruction *insn)
|
|||
|
||||
case MSP430_OP_XOR:
|
||||
if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
|
||||
insn->src_addr == 0xffff) {
|
||||
insn->src_addr == ALL_ONES) {
|
||||
insn->op = MSP430_OP_INV;
|
||||
insn->itype = MSP430_ITYPE_SINGLE;
|
||||
}
|
||||
|
@ -396,11 +398,12 @@ static void find_emulated_ops(struct msp430_instruction *insn)
|
|||
* successful, the decoded instruction is written into the structure
|
||||
* pointed to by insn.
|
||||
*/
|
||||
int dis_decode(const uint8_t *code, uint16_t offset, uint16_t len,
|
||||
int dis_decode(const uint8_t *code, address_t offset, address_t len,
|
||||
struct msp430_instruction *insn)
|
||||
{
|
||||
uint16_t op;
|
||||
int ret;
|
||||
address_t ds_mask = ALL_ONES;
|
||||
|
||||
memset(insn, 0, sizeof(*insn));
|
||||
|
||||
|
@ -439,12 +442,15 @@ int dis_decode(const uint8_t *code, uint16_t offset, uint16_t len,
|
|||
find_cgens(insn);
|
||||
find_emulated_ops(insn);
|
||||
|
||||
if (insn->is_byte_op) {
|
||||
if (insn->src_mode == MSP430_AMODE_IMMEDIATE)
|
||||
insn->src_addr &= 0xff;
|
||||
if (insn->dst_mode == MSP430_AMODE_IMMEDIATE)
|
||||
insn->dst_addr &= 0xff;
|
||||
}
|
||||
if (insn->dsize == MSP430_DSIZE_BYTE)
|
||||
ds_mask = 0xff;
|
||||
else if (insn->dsize == MSP430_DSIZE_WORD)
|
||||
ds_mask = 0xffff;
|
||||
|
||||
if (insn->src_mode == MSP430_AMODE_IMMEDIATE)
|
||||
insn->src_addr &= ds_mask;
|
||||
if (insn->dst_mode == MSP430_AMODE_IMMEDIATE)
|
||||
insn->dst_addr &= ds_mask;
|
||||
|
||||
insn->len = ret;
|
||||
return ret;
|
||||
|
|
24
dis.h
24
dis.h
|
@ -19,6 +19,7 @@
|
|||
#ifndef DIS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "util.h"
|
||||
|
||||
/* Addressing modes.
|
||||
*
|
||||
|
@ -98,6 +99,19 @@ typedef enum {
|
|||
MSP430_ITYPE_SINGLE
|
||||
} msp430_itype_t;
|
||||
|
||||
/* MSP430(X) data sizes.
|
||||
*
|
||||
* An address-word is a 20-bit value. When stored in memory, they are
|
||||
* stored as two 16-bit words in the following order:
|
||||
*
|
||||
* data[15:0], {12'b0, data[19:16]}
|
||||
*/
|
||||
typedef enum {
|
||||
MSP430_DSIZE_BYTE,
|
||||
MSP430_DSIZE_WORD,
|
||||
MSP430_DSIZE_AWORD
|
||||
} msp430_dsize_t;
|
||||
|
||||
/* MSP430 operations.
|
||||
*
|
||||
* Some of these are emulated instructions. Emulated instructions are
|
||||
|
@ -177,19 +191,19 @@ typedef enum {
|
|||
* For jump instructions, the target address is stored in dst_operand.
|
||||
*/
|
||||
struct msp430_instruction {
|
||||
uint16_t offset;
|
||||
address_t offset;
|
||||
int len;
|
||||
|
||||
msp430_op_t op;
|
||||
msp430_itype_t itype;
|
||||
int is_byte_op;
|
||||
msp430_dsize_t dsize;
|
||||
|
||||
msp430_amode_t src_mode;
|
||||
uint16_t src_addr;
|
||||
address_t src_addr;
|
||||
msp430_reg_t src_reg;
|
||||
|
||||
msp430_amode_t dst_mode;
|
||||
uint16_t dst_addr;
|
||||
address_t dst_addr;
|
||||
msp430_reg_t dst_reg;
|
||||
};
|
||||
|
||||
|
@ -203,7 +217,7 @@ struct msp430_instruction {
|
|||
* pointed to by insn.
|
||||
*/
|
||||
int dis_decode(const uint8_t *code,
|
||||
uint16_t offset, uint16_t len,
|
||||
address_t offset, address_t len,
|
||||
struct msp430_instruction *insn);
|
||||
|
||||
/* Look up names for registers and opcodes */
|
||||
|
|
27
rtools.c
27
rtools.c
|
@ -36,7 +36,7 @@
|
|||
*/
|
||||
|
||||
#define ISEARCH_OPCODE 0x0001
|
||||
#define ISEARCH_BW 0x0002
|
||||
#define ISEARCH_DSIZE 0x0002
|
||||
#define ISEARCH_SRC_ADDR 0x0004
|
||||
#define ISEARCH_DST_ADDR 0x0008
|
||||
#define ISEARCH_SRC_MODE 0x0010
|
||||
|
@ -80,13 +80,26 @@ static int isearch_opcode(cproc_t cp, const char *term, char **arg,
|
|||
static int isearch_bw(cproc_t cp, const char *term, char **arg,
|
||||
struct isearch_query *q)
|
||||
{
|
||||
if (q->flags & ISEARCH_BW) {
|
||||
if (q->flags & ISEARCH_DSIZE) {
|
||||
fprintf(stderr, "isearch: operand size already specified\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
q->flags |= ISEARCH_BW;
|
||||
q->insn.is_byte_op = (toupper(*term) == 'B');
|
||||
q->flags |= ISEARCH_DSIZE;
|
||||
switch (toupper(*term)) {
|
||||
case 'B':
|
||||
q->insn.dsize = MSP430_DSIZE_BYTE;
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
q->insn.dsize = MSP430_DSIZE_WORD;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
q->insn.dsize = MSP430_DSIZE_AWORD;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -268,8 +281,8 @@ static int isearch_match(const struct msp430_instruction *insn,
|
|||
insn->op != q->insn.op)
|
||||
return 0;
|
||||
|
||||
if ((q->flags & ISEARCH_BW) &&
|
||||
(q->insn.is_byte_op ? 1 : 0) != (insn->is_byte_op ? 1 : 0))
|
||||
if ((q->flags & ISEARCH_DSIZE) &&
|
||||
q->insn.dsize != insn->dsize)
|
||||
return 0;
|
||||
|
||||
if (q->flags & ISEARCH_SRC_ADDR) {
|
||||
|
@ -967,7 +980,7 @@ static const struct cproc_command rtools_commands[] = {
|
|||
" Search for an instruction matching certain search terms. These\n"
|
||||
" terms may be any of the following:\n"
|
||||
" opcode <opcode>\n"
|
||||
" byte|word\n"
|
||||
" byte|word|aword\n"
|
||||
" jump|single|double|noarg\n"
|
||||
" src <value>\n"
|
||||
" dst <value>\n"
|
||||
|
|
Loading…
Reference in New Issue