dis: decode MSP430X emulated instructions.
This commit is contained in:
parent
daee870b44
commit
ccc5854854
|
@ -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
151
dis.c
|
@ -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
22
dis.h
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue