Skip to content

Commit

Permalink
Lift MSP430 machine language to RzIL: first 3 instructions and 1 addr…
Browse files Browse the repository at this point in the history
…essing mode
  • Loading branch information
moste00 committed May 23, 2024
1 parent 60657d7 commit 4d28ad6
Show file tree
Hide file tree
Showing 10 changed files with 558 additions and 3 deletions.
58 changes: 57 additions & 1 deletion librz/arch/isa/msp430/msp430_disas.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,13 @@ static int decode_addressing_mode(ut16 instr, ut16 op1, ut16 op2, struct msp430_
switch (src) {
case MSP430_R3: /* CG2 */
snprintf(cmd->operands, sizeof(cmd->operands), "#0");
cmd->src_mode = IMM;
cmd->src = 0;
break;
default: /* register mode */
snprintf(cmd->operands, sizeof(cmd->operands), "%s", msp430_register_names[src]);
cmd->src_mode = REG;
cmd->src = src;
}
ret = 2;
break;
Expand All @@ -226,31 +230,45 @@ static int decode_addressing_mode(ut16 instr, ut16 op1, ut16 op2, struct msp430_
switch (src) {
case MSP430_PC: /* symbolic mode */
snprintf(cmd->operands, sizeof(cmd->operands), "0x%04x", op1);
cmd->src_mode = SYM;
cmd->src = op1;
srcOperInCodeWord = 1;
break;
case MSP430_R3: /* CG2 */
snprintf(cmd->operands, sizeof(cmd->operands), "%s", "#1");
cmd->src_mode = IMM;
cmd->src = 1;
ret = 2;
break;
case MSP430_SR: /* absolute mode */
snprintf(cmd->operands, sizeof(cmd->operands), "&0x%04x", op1);
cmd->src_mode = ABS;
cmd->src = op1;
srcOperInCodeWord = 1;
break;
default: /* indexed mode */
snprintf(cmd->operands, sizeof(cmd->operands), "0x%x(%s)", op1, msp430_register_names[src]);
cmd->src_mode = INDX;
cmd->src = (op1 << 16) | src;
srcOperInCodeWord = 1;
}
break;
case 2:
switch (src) {
case MSP430_SR: /* CG1 */
snprintf(cmd->operands, sizeof(cmd->operands), "#4");
cmd->src_mode = IMM;
cmd->src = 4;
break;
case MSP430_R3: /* CG2 */
snprintf(cmd->operands, sizeof(cmd->operands), "#2");
cmd->src_mode = IMM;
cmd->src = 2;
break;
default: /* indirect register mode */
snprintf(cmd->operands, sizeof(cmd->operands), "@%s", msp430_register_names[src]);
cmd->src_mode = IND_REG;
cmd->src = src;
}
ret = 2;
break;
Expand All @@ -259,17 +277,25 @@ static int decode_addressing_mode(ut16 instr, ut16 op1, ut16 op2, struct msp430_
switch (src) {
case MSP430_SR: /* CG1 */
snprintf(cmd->operands, sizeof(cmd->operands), "#8");
cmd->src_mode = IMM;
cmd->src = 8;
break;
case MSP430_R3: /* CG2 */
snprintf(cmd->operands, sizeof(cmd->operands), "#-1");
cmd->src_mode = IMM;
cmd->src = -1;
break;
case MSP430_PC: /* immediate mode */
snprintf(cmd->operands, sizeof(cmd->operands), "#0x%04x", op1);
cmd->src_mode = IMM;
cmd->src = op1;
srcOperInCodeWord = 1;
ret = 4;
break;
default: /* indirect autoincrement mode */
snprintf(cmd->operands, sizeof(cmd->operands), "@%s+", msp430_register_names[src]);
cmd->src_mode = IND_AUTOINC;
cmd->src = src;
}
break;
}
Expand All @@ -278,6 +304,8 @@ static int decode_addressing_mode(ut16 instr, ut16 op1, ut16 op2, struct msp430_
switch (ad) {
case 0: /* register mode */
snprintf(dstbuf, sizeof(dstbuf), ", %s", msp430_register_names[dst]);
cmd->dst_mode = REG;
cmd->dst = dst;
break;
case 1:
/* check addr. mode of source operand */
Expand All @@ -291,12 +319,18 @@ static int decode_addressing_mode(ut16 instr, ut16 op1, ut16 op2, struct msp430_
switch (get_dst(instr)) {
case MSP430_PC: /* symbolic mode */
snprintf(dstbuf, sizeof(dstbuf), ", 0x%04x", op);
cmd->dst_mode = SYM;
cmd->dst = op;
break;
case MSP430_SR: /* absolute mode */
snprintf(dstbuf, sizeof(dstbuf), ", &0x%04x", op);
cmd->dst_mode = ABS;
cmd->dst = op;
break;
default: /* indexed mode */
snprintf(dstbuf, sizeof(dstbuf), ", 0x%x(%s)", op, msp430_register_names[dst]);
cmd->dst_mode = INDX;
cmd->dst = dst;
}
break;
}
Expand All @@ -310,7 +344,8 @@ static int decode_twoop_opcode(ut16 instr, ut16 op1, ut16 op2, struct msp430_cmd
ut8 opcode = get_twoop_opcode(instr);

snprintf(cmd->instr, sizeof(cmd->instr), "%s", two_op_instrs[opcode]);
if (get_bw(instr)) {
cmd->is_byte = get_bw(instr);
if (cmd->is_byte) {
strncat(cmd->instr, ".b", sizeof(cmd->instr) - 1 - strlen(cmd->instr));
}

Expand Down Expand Up @@ -370,10 +405,14 @@ static int decode_oneop_opcode(ut16 instr, ut16 op, struct msp430_cmd *cmd) {
switch (get_dst(instr)) {
case MSP430_R3:
snprintf(cmd->operands, sizeof(cmd->operands), "#0");
cmd->dst = 0;
cmd->dst_mode = IMM;
break;
default:
snprintf(cmd->operands, sizeof(cmd->operands),
"%s", msp430_register_names[get_dst(instr)]);
cmd->dst = get_dst(instr);
cmd->dst_mode = REG;
}
ret = 2;
break;
Expand All @@ -383,38 +422,54 @@ static int decode_oneop_opcode(ut16 instr, ut16 op, struct msp430_cmd *cmd) {
switch (get_dst(instr)) {
case MSP430_R3:
snprintf(cmd->operands, sizeof(cmd->operands), "#1");
cmd->dst = 1;
cmd->dst_mode = IMM;
/* this is an unusual encoding in that there's no index word */
ret = 2;
break;
case MSP430_PC:
snprintf(cmd->operands, sizeof(cmd->operands), "0x%04x", op);
cmd->dst = op;
cmd->dst_mode = SYM;
break;
case MSP430_SR:
snprintf(cmd->operands, sizeof(cmd->operands), "&0x%04x", op);
cmd->dst = op;
cmd->dst_mode = ABS;
break;
default:
snprintf(cmd->operands, sizeof(cmd->operands),
"0x%x(%s)", op, msp430_register_names[get_dst(instr)]);
cmd->dst = (op << 16) | get_dst(instr);
cmd->dst_mode = INDX;
}

break;
case 2:
switch (get_dst(instr)) {
case MSP430_SR:
snprintf(cmd->operands, sizeof(cmd->operands), "#4");
cmd->dst = 4;
cmd->dst_mode = IMM;
break;
case MSP430_R3:
snprintf(cmd->operands, sizeof(cmd->operands), "#2");
cmd->dst = 2;
cmd->dst_mode = IMM;
break;
default:
snprintf(cmd->operands, sizeof(cmd->operands),
"@%s", msp430_register_names[get_dst(instr)]);
cmd->dst = get_dst(instr);
cmd->dst_mode = IND_REG;
}

ret = 2;
break;
case 3:
snprintf(cmd->operands, sizeof(cmd->operands), "#0x%04x", op);
cmd->dst = op;
cmd->dst_mode = IMM;
ret = 4;
break;
default:
Expand All @@ -427,6 +482,7 @@ static int decode_oneop_opcode(ut16 instr, ut16 op, struct msp430_cmd *cmd) {
}

cmd->type = MSP430_ONEOP;
cmd->is_byte = get_bw(instr);

return ret;
}
Expand Down
19 changes: 19 additions & 0 deletions librz/arch/isa/msp430/msp430_disas.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ enum msp430_registers {
MSP430_R15,
};

typedef enum Msp430AddressingMode {
REG,
INDX,
SYM,
ABS,
IND_REG,
IND_AUTOINC,
IMM
} Msp430AddressingMode;

struct msp430_cmd {
ut8 type;
ut8 opcode;
Expand All @@ -89,11 +99,20 @@ struct msp430_cmd {
// Length of array: 'i', 'n', 'v', 'a', 'l', 'i', 'd', '\0'
// (This is longer than any real assembly mnemonic.)
char instr[7 + 1];
// does it have a .b ?
bool is_byte;

// Null-delimited string representation of assembly operands.
// Length of array: 2 * ('0', 'x', 4-digit hexadecimal numeral, '(', 'r', 2-digit
// decimal numeral, ')'), ',', ' ', '\0'
char operands[2 * (2 + 4 + 2 + 3) + 2 + 1];

// The source and the dst of the operands, along with their modes
// This info is contained in the strings above, but parsing strings to obtain is ugly so we replicate it here
ut32 src;
ut32 dst;
Msp430AddressingMode src_mode;
Msp430AddressingMode dst_mode;
};

int msp430_decode_command(const ut8 *instr, int len, struct msp430_cmd *cmd);
Expand Down
Loading

0 comments on commit 4d28ad6

Please sign in to comment.