dis: decode MSP430X emulated instructions.

This commit is contained in:
Daniel Beer 2010-08-10 16:26:45 +12:00
parent daee870b44
commit ccc5854854
3 changed files with 173 additions and 3 deletions

View File

@ -141,7 +141,8 @@ static int dis_format(stab_t stab, char *buf, int max_len,
/* Don't show the .A suffix for these instructions */
if (insn->op == MSP430_OP_MOVA || insn->op == MSP430_OP_CMPA ||
insn->op == MSP430_OP_SUBA || insn->op == MSP430_OP_ADDA)
insn->op == MSP430_OP_SUBA || insn->op == MSP430_OP_ADDA ||
insn->op == MSP430_OP_BRA || insn->op == MSP430_OP_RETA)
suffix = "";
len = snprintf(buf + total, max_len - total,

151
dis.c
View File

@ -465,6 +465,31 @@ static void find_emulated_ops(struct msp430_instruction *insn)
}
break;
case MSP430_OP_ADDA:
if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
insn->src_addr == 2) {
insn->op = MSP430_OP_INCDA;
insn->itype = MSP430_ITYPE_SINGLE;
}
break;
case MSP430_OP_ADDX:
if (insn->src_mode == MSP430_AMODE_IMMEDIATE) {
if (insn->src_addr == 1) {
insn->op = MSP430_OP_INCX;
insn->itype = MSP430_ITYPE_SINGLE;
} else if (insn->src_addr == 2) {
insn->op = MSP430_OP_INCDX;
insn->itype = MSP430_ITYPE_SINGLE;
}
} else if (insn->dst_mode == insn->src_mode &&
insn->dst_reg == insn->src_reg &&
insn->dst_addr == insn->src_addr) {
insn->op = MSP430_OP_RLAX;
insn->itype = MSP430_ITYPE_SINGLE;
}
break;
case MSP430_OP_ADDC:
if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
!insn->src_addr) {
@ -478,6 +503,19 @@ static void find_emulated_ops(struct msp430_instruction *insn)
}
break;
case MSP430_OP_ADDCX:
if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
!insn->src_addr) {
insn->op = MSP430_OP_ADCX;
insn->itype = MSP430_ITYPE_SINGLE;
} else if (insn->dst_mode == insn->src_mode &&
insn->dst_reg == insn->src_reg &&
insn->dst_addr == insn->src_addr) {
insn->op = MSP430_OP_RLCX;
insn->itype = MSP430_ITYPE_SINGLE;
}
break;
case MSP430_OP_BIC:
if (insn->dst_mode == MSP430_AMODE_REGISTER &&
insn->dst_reg == MSP430_REG_SR &&
@ -526,6 +564,22 @@ static void find_emulated_ops(struct msp430_instruction *insn)
}
break;
case MSP430_OP_CMPA:
if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
!insn->src_addr) {
insn->op = MSP430_OP_TSTA;
insn->itype = MSP430_ITYPE_SINGLE;
}
break;
case MSP430_OP_CMPX:
if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
!insn->src_addr) {
insn->op = MSP430_OP_TSTX;
insn->itype = MSP430_ITYPE_SINGLE;
}
break;
case MSP430_OP_DADD:
if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
!insn->src_addr) {
@ -534,6 +588,14 @@ static void find_emulated_ops(struct msp430_instruction *insn)
}
break;
case MSP430_OP_DADDX:
if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
!insn->src_addr) {
insn->op = MSP430_OP_DADCX;
insn->itype = MSP430_ITYPE_SINGLE;
}
break;
case MSP430_OP_MOV:
if (insn->src_mode == MSP430_AMODE_INDIRECT_INC &&
insn->src_reg == MSP430_REG_SP) {
@ -565,6 +627,37 @@ static void find_emulated_ops(struct msp430_instruction *insn)
}
break;
case MSP430_OP_MOVA:
if (insn->src_mode == MSP430_AMODE_INDIRECT_INC &&
insn->src_reg == MSP430_REG_SP) {
if (insn->dst_mode == MSP430_AMODE_REGISTER &&
insn->dst_reg == MSP430_REG_PC) {
insn->op = MSP430_OP_RETA;
insn->itype = MSP430_ITYPE_NOARG;
} else {
insn->op = MSP430_OP_POPX;
insn->itype = MSP430_ITYPE_SINGLE;
}
} else if (insn->dst_mode == MSP430_AMODE_REGISTER &&
insn->dst_reg == MSP430_REG_PC) {
insn->op = MSP430_OP_BRA;
insn->itype = MSP430_ITYPE_SINGLE;
insn->dst_mode = insn->src_mode;
insn->dst_reg = insn->src_reg;
insn->dst_addr = insn->src_addr;
} else if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
!insn->src_addr) {
if (insn->dst_mode == MSP430_AMODE_REGISTER &&
insn->dst_reg == MSP430_REG_R3) {
insn->op = MSP430_OP_NOP;
insn->itype = MSP430_ITYPE_NOARG;
} else {
insn->op = MSP430_OP_CLRX;
insn->itype = MSP430_ITYPE_SINGLE;
}
}
break;
case MSP430_OP_SUB:
if (insn->src_mode == MSP430_AMODE_IMMEDIATE) {
if (insn->src_addr == 1) {
@ -577,6 +670,26 @@ static void find_emulated_ops(struct msp430_instruction *insn)
}
break;
case MSP430_OP_SUBA:
if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
insn->src_addr == 2) {
insn->op = MSP430_OP_DECDA;
insn->itype = MSP430_ITYPE_SINGLE;
}
break;
case MSP430_OP_SUBX:
if (insn->src_mode == MSP430_AMODE_IMMEDIATE) {
if (insn->src_addr == 1) {
insn->op = MSP430_OP_DECX;
insn->itype = MSP430_ITYPE_SINGLE;
} else if (insn->src_addr == 2) {
insn->op = MSP430_OP_DECDX;
insn->itype = MSP430_ITYPE_SINGLE;
}
}
break;
case MSP430_OP_SUBC:
if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
!insn->src_addr) {
@ -585,6 +698,14 @@ static void find_emulated_ops(struct msp430_instruction *insn)
}
break;
case MSP430_OP_SUBCX:
if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
!insn->src_addr) {
insn->op = MSP430_OP_SECX;
insn->itype = MSP430_ITYPE_SINGLE;
}
break;
case MSP430_OP_XOR:
if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
insn->src_addr == ALL_ONES) {
@ -593,6 +714,14 @@ static void find_emulated_ops(struct msp430_instruction *insn)
}
break;
case MSP430_OP_XORX:
if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
insn->src_addr == ALL_ONES) {
insn->op = MSP430_OP_INVX;
insn->itype = MSP430_ITYPE_SINGLE;
}
break;
default: break;
}
}
@ -798,7 +927,27 @@ static const struct {
{MSP430_OP_RRCM, "RRCM"},
{MSP430_OP_RRAM, "RRAM"},
{MSP430_OP_RLAM, "RLAM"},
{MSP430_OP_RRUM, "RRUM"}
{MSP430_OP_RRUM, "RRUM"},
/* MSP430X emulated instructions */
{MSP430_OP_ADCX, "ADCX"},
{MSP430_OP_BRA, "BRA"},
{MSP430_OP_RETA, "RETA"},
{MSP430_OP_CLRX, "CLRX"},
{MSP430_OP_DADCX, "DADCX"},
{MSP430_OP_DECX, "DECX"},
{MSP430_OP_DECDA, "DECDA"},
{MSP430_OP_DECDX, "DECDX"},
{MSP430_OP_INCX, "INCX"},
{MSP430_OP_INCDA, "INCDA"},
{MSP430_OP_INVX, "INVX"},
{MSP430_OP_RLAX, "RLAX"},
{MSP430_OP_RLCX, "RLCX"},
{MSP430_OP_SECX, "SECX"},
{MSP430_OP_TSTA, "TSTA"},
{MSP430_OP_TSTX, "TSTX"},
{MSP430_OP_POPX, "POPX"},
{MSP430_OP_INCDX, "INCDX"}
};
/* Return the mnemonic for an operation, if possible. */

22
dis.h
View File

@ -224,7 +224,27 @@ typedef enum {
MSP430_OP_RRCM = 0x0040,
MSP430_OP_RRAM = 0x0140,
MSP430_OP_RLAM = 0x0240,
MSP430_OP_RRUM = 0x0340
MSP430_OP_RRUM = 0x0340,
/* MSP430X emulated instructions */
MSP430_OP_ADCX = 0x40000,
MSP430_OP_BRA = 0x40001,
MSP430_OP_RETA = 0x40002,
MSP430_OP_CLRX = 0x40003,
MSP430_OP_DADCX = 0x40004,
MSP430_OP_DECX = 0x40005,
MSP430_OP_DECDA = 0x40006,
MSP430_OP_DECDX = 0x40007,
MSP430_OP_INCX = 0x40008,
MSP430_OP_INCDA = 0x40009,
MSP430_OP_INVX = 0x4000A,
MSP430_OP_RLAX = 0x4000B,
MSP430_OP_RLCX = 0x4000C,
MSP430_OP_SECX = 0x4000D,
MSP430_OP_TSTA = 0x4000E,
MSP430_OP_TSTX = 0x4000F,
MSP430_OP_POPX = 0x40010,
MSP430_OP_INCDX = 0x40011,
} msp430_op_t;
/* This represents a decoded instruction. All decoded addresses are