Rizin
unix-like reverse engineering framework and cli tools
msp430_disas.c File Reference
#include <rz_types.h>
#include <rz_util.h>
#include "msp430_disas.h"

Go to the source code of this file.

Enumerations

enum  { MSP430_TWOOP_OPCODE_INVALID = 0 , MSP430_TWOOP_OPCODE_SINGLEOP , MSP430_TWOOP_OPCODE_JUMP2 , MSP430_TWOOP_OPCODE_JUMP3 }
 

Functions

static ut8 get_twoop_opcode (ut16 instr)
 
static ut8 get_as (ut16 instr)
 
static ut8 get_bw (ut16 instr)
 
static ut8 get_ad (ut16 instr)
 
static int get_src (ut16 instr)
 
static int get_dst (ut16 instr)
 
static void remove_first_operand (struct msp430_cmd *cmd)
 
static void remove_second_operand (struct msp430_cmd *cmd)
 
static int decode_emulation (ut16 instr, struct msp430_cmd *cmd)
 
static int decode_addressing_mode (ut16 instr, ut16 op1, ut16 op2, struct msp430_cmd *cmd)
 
static int decode_twoop_opcode (ut16 instr, ut16 op1, ut16 op2, struct msp430_cmd *cmd)
 
static ut8 get_jmp_opcode (ut16 instr)
 
static ut8 get_jmp_cond (ut16 instr)
 
static void decode_jmp (ut16 instr, struct msp430_cmd *cmd)
 
static int get_oneop_opcode (ut16 instr)
 
static int decode_oneop_opcode (ut16 instr, ut16 op, struct msp430_cmd *cmd)
 
int msp430_decode_command (const ut8 *in, int len, struct msp430_cmd *cmd)
 

Variables

static const char * msp430_register_names []
 
static const char * two_op_instrs []
 
static const char * one_op_instrs []
 
static const char * jmp_instrs []
 

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
MSP430_TWOOP_OPCODE_INVALID 
MSP430_TWOOP_OPCODE_SINGLEOP 
MSP430_TWOOP_OPCODE_JUMP2 
MSP430_TWOOP_OPCODE_JUMP3 

Definition at line 434 of file msp430_disas.c.

434  {
439 };
@ MSP430_TWOOP_OPCODE_JUMP3
Definition: msp430_disas.c:438
@ MSP430_TWOOP_OPCODE_INVALID
Definition: msp430_disas.c:435
@ MSP430_TWOOP_OPCODE_JUMP2
Definition: msp430_disas.c:437
@ MSP430_TWOOP_OPCODE_SINGLEOP
Definition: msp430_disas.c:436

Function Documentation

◆ decode_addressing_mode()

static int decode_addressing_mode ( ut16  instr,
ut16  op1,
ut16  op2,
struct msp430_cmd cmd 
)
static

Definition at line 199 of file msp430_disas.c.

199  {
200  int ret = 0, srcOperInCodeWord = 0;
201  ut8 as, ad, src, dst;
202  ut16 op;
203  char dstbuf[16];
204 
205  memset(dstbuf, 0, sizeof(dstbuf));
206 
207  as = get_as(instr);
208  ad = get_ad(instr);
209  src = get_src(instr);
210  dst = get_dst(instr);
211 
212  /* addressing mode of source operand */
213  switch (as) {
214  case 0:
215  switch (src) {
216  case MSP430_R3: /* CG2 */
217  snprintf(cmd->operands, sizeof(cmd->operands), "#0");
218  break;
219  default: /* register mode */
220  snprintf(cmd->operands, sizeof(cmd->operands), "%s", msp430_register_names[src]);
221  }
222  ret = 2;
223  break;
224  case 1:
225  ret = 4;
226  switch (src) {
227  case MSP430_PC: /* symbolic mode */
228  snprintf(cmd->operands, sizeof(cmd->operands), "0x%04x", op1);
229  srcOperInCodeWord = 1;
230  break;
231  case MSP430_R3: /* CG2 */
232  snprintf(cmd->operands, sizeof(cmd->operands), "%s", "#1");
233  ret = 2;
234  break;
235  case MSP430_SR: /* absolute mode */
236  snprintf(cmd->operands, sizeof(cmd->operands), "&0x%04x", op1);
237  srcOperInCodeWord = 1;
238  break;
239  default: /* indexed mode */
240  snprintf(cmd->operands, sizeof(cmd->operands), "0x%x(%s)", op1, msp430_register_names[src]);
241  srcOperInCodeWord = 1;
242  }
243  break;
244  case 2:
245  switch (src) {
246  case MSP430_SR: /* CG1 */
247  snprintf(cmd->operands, sizeof(cmd->operands), "#4");
248  break;
249  case MSP430_R3: /* CG2 */
250  snprintf(cmd->operands, sizeof(cmd->operands), "#2");
251  break;
252  default: /* indirect register mode */
253  snprintf(cmd->operands, sizeof(cmd->operands), "@%s", msp430_register_names[src]);
254  }
255  ret = 2;
256  break;
257  case 3:
258  ret = 2;
259  switch (src) {
260  case MSP430_SR: /* CG1 */
261  snprintf(cmd->operands, sizeof(cmd->operands), "#8");
262  break;
263  case MSP430_R3: /* CG2 */
264  snprintf(cmd->operands, sizeof(cmd->operands), "#-1");
265  break;
266  case MSP430_PC: /* immediate mode */
267  snprintf(cmd->operands, sizeof(cmd->operands), "#0x%04x", op1);
268  srcOperInCodeWord = 1;
269  ret = 4;
270  break;
271  default: /* indirect autoincrement mode */
272  snprintf(cmd->operands, sizeof(cmd->operands), "@%s+", msp430_register_names[src]);
273  }
274  break;
275  }
276 
277  /* addressing mode of destination operand */
278  switch (ad) {
279  case 0: /* register mode */
280  snprintf(dstbuf, sizeof(dstbuf), ", %s", msp430_register_names[dst]);
281  break;
282  case 1:
283  /* check addr. mode of source operand */
284  if (srcOperInCodeWord != 0) {
285  op = op2;
286  ret = 6;
287  } else {
288  op = op1;
289  ret = 4;
290  }
291  switch (get_dst(instr)) {
292  case MSP430_PC: /* symbolic mode */
293  snprintf(dstbuf, sizeof(dstbuf), ", 0x%04x", op);
294  break;
295  case MSP430_SR: /* absolute mode */
296  snprintf(dstbuf, sizeof(dstbuf), ", &0x%04x", op);
297  break;
298  default: /* indexed mode */
299  snprintf(dstbuf, sizeof(dstbuf), ", 0x%x(%s)", op, msp430_register_names[dst]);
300  }
301  break;
302  }
303 
304  strncat(cmd->operands, dstbuf, sizeof(cmd->operands) - 1 - strlen(cmd->operands));
305  decode_emulation(instr, cmd);
306  return ret;
307 }
ut8 op
Definition: 6502dis.c:13
lzma_index * src
Definition: index.h:567
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
uint16_t ut16
snprintf
Definition: kernel.h:364
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
char * dst
Definition: lz4.h:724
static int get_src(ut16 instr)
Definition: msp430_disas.c:83
static int get_dst(ut16 instr)
Definition: msp430_disas.c:87
static ut8 get_as(ut16 instr)
Definition: msp430_disas.c:71
static int decode_emulation(ut16 instr, struct msp430_cmd *cmd)
Definition: msp430_disas.c:107
static ut8 get_ad(ut16 instr)
Definition: msp430_disas.c:79
static const char * msp430_register_names[]
Definition: msp430_disas.c:12
@ MSP430_SR
Definition: msp430_disas.h:65
@ MSP430_PC
Definition: msp430_disas.h:63
@ MSP430_R3
Definition: msp430_disas.h:66
Definition: dis.c:32

References cmd, decode_emulation(), dst, get_ad(), get_as(), get_dst(), get_src(), memset(), MSP430_PC, MSP430_R3, msp430_register_names, MSP430_SR, op, snprintf, and src.

Referenced by decode_twoop_opcode().

◆ decode_emulation()

static int decode_emulation ( ut16  instr,
struct msp430_cmd cmd 
)
static

Definition at line 107 of file msp430_disas.c.

107  {
108  int ret = -1;
109  ut8 as, ad, src, dst, bw, opcode;
110 
111  as = get_as(instr);
112  ad = get_ad(instr);
113  src = get_src(instr);
114  dst = get_dst(instr);
115  bw = get_bw(instr);
116  opcode = get_twoop_opcode(instr);
117 
118  if (opcode == MSP430_ADDC && as == 0 && src == MSP430_R3) {
119  snprintf(cmd->instr, sizeof(cmd->instr), "%s", bw ? "adc.b" : "adc");
120  snprintf(cmd->operands, sizeof(cmd->operands), "%s", msp430_register_names[dst]);
121  } else if (opcode == MSP430_MOV && as == 0 && src == MSP430_R3) {
122  if (ad == 0 && dst == MSP430_R3) {
123  snprintf(cmd->instr, sizeof(cmd->instr), "nop");
124  cmd->operands[0] = '\0';
125  } else {
126  snprintf(cmd->instr, sizeof(cmd->instr), "%s", bw ? "clr.b" : "clr");
128  }
129  } else if (opcode == MSP430_MOV && as == 3 && src == MSP430_SP) {
130  if (dst == MSP430_PC) {
131  snprintf(cmd->instr, sizeof(cmd->instr), "ret");
132  cmd->type = MSP430_ONEOP;
133  cmd->opcode = MSP430_RETI;
134  cmd->operands[0] = '\0';
135  } else {
136  snprintf(cmd->instr, sizeof(cmd->instr), "%s", bw ? "pop.b" : "pop");
138  }
139  } else if (opcode == MSP430_MOV && ad == 0 && dst == MSP430_PC) {
140  snprintf(cmd->instr, sizeof(cmd->instr), "%s", "br");
142  } else if (opcode == MSP430_BIC && as == 2 && src == MSP430_SR && dst == MSP430_SR && ad == 0) {
143  snprintf(cmd->instr, sizeof(cmd->instr), "%s", "clrn");
144  cmd->operands[0] = '\0';
145  } else if (opcode == MSP430_BIC && as == 2 && src == MSP430_R3 && dst == MSP430_SR && ad == 0) {
146  snprintf(cmd->instr, sizeof(cmd->instr), "%s", "clrz");
147  cmd->operands[0] = '\0';
148  } else if (opcode == MSP430_BIC && as == 3 && src == MSP430_SR && dst == MSP430_SR && ad == 0) {
149  snprintf(cmd->instr, sizeof(cmd->instr), "%s", "dint");
150  cmd->operands[0] = '\0';
151  } else if (opcode == MSP430_BIS && as == 3 && src == MSP430_SR && dst == MSP430_SR && ad == 0) {
152  snprintf(cmd->instr, sizeof(cmd->instr), "%s", "eint");
153  cmd->operands[0] = '\0';
154  } else if (opcode == MSP430_DADD && as == 0 && src == MSP430_R3) {
155  snprintf(cmd->instr, sizeof(cmd->instr), "%s", bw ? "dadc.b" : "dadc");
157  } else if (opcode == MSP430_SUB && as == 1 && src == MSP430_R3) {
158  snprintf(cmd->instr, sizeof(cmd->instr), "%s", bw ? "dec.b" : "dec");
160  } else if (opcode == MSP430_SUB && as == 2 && src == MSP430_R3) {
161  snprintf(cmd->instr, sizeof(cmd->instr), "%s", bw ? "decd.b" : "decd");
163  } else if (opcode == MSP430_ADD && as == 1 && src == MSP430_R3) {
164  snprintf(cmd->instr, sizeof(cmd->instr), "%s", bw ? "inc.b" : "inc");
166  } else if (opcode == MSP430_ADD && as == 2 && src == MSP430_R3) {
167  snprintf(cmd->instr, sizeof(cmd->instr), "%s", bw ? "incd.b" : "incd");
169  } else if (opcode == MSP430_XOR && as == 3 && src == MSP430_R3) {
170  snprintf(cmd->instr, sizeof(cmd->instr), "%s", bw ? "inv.b" : "inv");
172  } else if (opcode == MSP430_ADD && src == dst) {
173  snprintf(cmd->instr, sizeof(cmd->instr), "%s", bw ? "rla.b" : "rla");
175  } else if (opcode == MSP430_ADDC && src == dst) {
176  snprintf(cmd->instr, sizeof(cmd->instr), "%s", bw ? "rlc.b" : "rlc");
178  } else if (opcode == MSP430_SUBC && as == 0 && src == MSP430_R3) {
179  snprintf(cmd->instr, sizeof(cmd->instr), "%s", bw ? "sbc.b" : "sbc");
181  } else if (opcode == MSP430_BIS && as == 1 && src == MSP430_R3 && dst == MSP430_SR && ad == 0) {
182  snprintf(cmd->instr, sizeof(cmd->instr), "setc");
183  cmd->operands[0] = '\0';
184  } else if (opcode == MSP430_BIS && as == 2 && src == MSP430_SR && dst == MSP430_SR && ad == 0) {
185  snprintf(cmd->instr, sizeof(cmd->instr), "setn");
186  cmd->operands[0] = '\0';
187  } else if (opcode == MSP430_BIS && as == 2 && src == MSP430_R3 && dst == MSP430_SR && ad == 0) {
188  snprintf(cmd->instr, sizeof(cmd->instr), "setz");
189  cmd->operands[0] = '\0';
190  } else if (opcode == MSP430_CMP && as == 0 && src == MSP430_R3) {
191  snprintf(cmd->instr, sizeof(cmd->instr), "%s", bw ? "tst.b" : "tst");
193  }
194 
195  return ret;
196 }
static void remove_second_operand(struct msp430_cmd *cmd)
Definition: msp430_disas.c:98
static ut8 get_twoop_opcode(ut16 instr)
Definition: msp430_disas.c:67
static ut8 get_bw(ut16 instr)
Definition: msp430_disas.c:75
static void remove_first_operand(struct msp430_cmd *cmd)
Definition: msp430_disas.c:91
@ MSP430_ONEOP
Definition: msp430_disas.h:56
@ MSP430_SUBC
Definition: msp430_disas.h:37
@ MSP430_MOV
Definition: msp430_disas.h:34
@ MSP430_CMP
Definition: msp430_disas.h:39
@ MSP430_BIC
Definition: msp430_disas.h:42
@ MSP430_XOR
Definition: msp430_disas.h:44
@ MSP430_SUB
Definition: msp430_disas.h:38
@ MSP430_DADD
Definition: msp430_disas.h:40
@ MSP430_BIS
Definition: msp430_disas.h:43
@ MSP430_ADD
Definition: msp430_disas.h:35
@ MSP430_ADDC
Definition: msp430_disas.h:36
@ MSP430_RETI
Definition: msp430_disas.h:17
@ MSP430_SP
Definition: msp430_disas.h:64

References cmd, dst, get_ad(), get_as(), get_bw(), get_dst(), get_src(), get_twoop_opcode(), MSP430_ADD, MSP430_ADDC, MSP430_BIC, MSP430_BIS, MSP430_CMP, MSP430_DADD, MSP430_MOV, MSP430_ONEOP, MSP430_PC, MSP430_R3, msp430_register_names, MSP430_RETI, MSP430_SP, MSP430_SR, MSP430_SUB, MSP430_SUBC, MSP430_XOR, remove_first_operand(), remove_second_operand(), snprintf, and src.

Referenced by decode_addressing_mode().

◆ decode_jmp()

static void decode_jmp ( ut16  instr,
struct msp430_cmd cmd 
)
static

Definition at line 329 of file msp430_disas.c.

329  {
330  ut16 addr;
331 
332  snprintf(cmd->instr, sizeof(cmd->instr), "%s", jmp_instrs[get_jmp_cond(instr)]);
333 
334  addr = instr & 0x3FF;
335 
336  cmd->jmp_addr = addr >= 0x300 ? (st16)((0xFE00 | addr) * 2 + 2) : (addr & 0x1FF) * 2 + 2;
337  snprintf(cmd->operands, sizeof(cmd->operands), "$%c0x%04x", addr >= 0x300 ? '-' : '+',
338  addr >= 0x300 ? 0x400 - ((addr & 0x1FF) * 2 + 2) : (addr & 0x1FF) * 2 + 2);
339 
340  cmd->jmp_cond = get_jmp_cond(instr);
341  cmd->opcode = get_jmp_opcode(instr);
342  cmd->type = MSP430_JUMP;
343 }
static const char * jmp_instrs[]
Definition: msp430_disas.c:56
static ut8 get_jmp_opcode(ut16 instr)
Definition: msp430_disas.c:321
static ut8 get_jmp_cond(ut16 instr)
Definition: msp430_disas.c:325
@ MSP430_JUMP
Definition: msp430_disas.h:58
#define st16
Definition: rz_types_base.h:14
static int addr
Definition: z80asm.c:58

References addr, cmd, get_jmp_cond(), get_jmp_opcode(), jmp_instrs, MSP430_JUMP, snprintf, and st16.

Referenced by msp430_decode_command().

◆ decode_oneop_opcode()

static int decode_oneop_opcode ( ut16  instr,
ut16  op,
struct msp430_cmd cmd 
)
static

Definition at line 349 of file msp430_disas.c.

349  {
350  int ret = 2;
351  ut8 as, opcode;
352 
353  opcode = get_oneop_opcode(instr);
354 
355  as = get_as(instr);
356 
357  snprintf(cmd->instr, sizeof(cmd->instr), "%s", one_op_instrs[opcode]);
358 
359  cmd->opcode = get_oneop_opcode(instr);
360 
361  switch (get_oneop_opcode(instr)) {
362  case MSP430_RRC:
363  case MSP430_SWPB:
364  case MSP430_RRA:
365  case MSP430_SXT:
366  case MSP430_PUSH:
367  case MSP430_CALL:
368  switch (as) {
369  case 0:
370  switch (get_dst(instr)) {
371  case MSP430_R3:
372  snprintf(cmd->operands, sizeof(cmd->operands), "#0");
373  break;
374  default:
375  snprintf(cmd->operands, sizeof(cmd->operands),
376  "%s", msp430_register_names[get_dst(instr)]);
377  }
378  ret = 2;
379  break;
380  case 1:
381  /* most of these instructions take another word as an immediate */
382  ret = 4;
383  switch (get_dst(instr)) {
384  case MSP430_R3:
385  snprintf(cmd->operands, sizeof(cmd->operands), "#1");
386  /* this is an unusual encoding in that there's no index word */
387  ret = 2;
388  break;
389  case MSP430_PC:
390  snprintf(cmd->operands, sizeof(cmd->operands), "0x%04x", op);
391  break;
392  case MSP430_SR:
393  snprintf(cmd->operands, sizeof(cmd->operands), "&0x%04x", op);
394  break;
395  default:
396  snprintf(cmd->operands, sizeof(cmd->operands),
397  "0x%x(%s)", op, msp430_register_names[get_dst(instr)]);
398  }
399 
400  break;
401  case 2:
402  switch (get_dst(instr)) {
403  case MSP430_SR:
404  snprintf(cmd->operands, sizeof(cmd->operands), "#4");
405  break;
406  case MSP430_R3:
407  snprintf(cmd->operands, sizeof(cmd->operands), "#2");
408  break;
409  default:
410  snprintf(cmd->operands, sizeof(cmd->operands),
411  "@%s", msp430_register_names[get_dst(instr)]);
412  }
413 
414  ret = 2;
415  break;
416  case 3:
417  snprintf(cmd->operands, sizeof(cmd->operands), "#0x%04x", op);
418  ret = 4;
419  break;
420  default:
421  ret = -1;
422  }
423  break;
424  case MSP430_RETI:
425  cmd->operands[0] = '\0';
426  break;
427  }
428 
429  cmd->type = MSP430_ONEOP;
430 
431  return ret;
432 }
static const char * one_op_instrs[]
Definition: msp430_disas.c:46
static int get_oneop_opcode(ut16 instr)
Definition: msp430_disas.c:345
@ MSP430_RRA
Definition: msp430_disas.h:13
@ MSP430_SXT
Definition: msp430_disas.h:14
@ MSP430_RRC
Definition: msp430_disas.h:11
@ MSP430_PUSH
Definition: msp430_disas.h:15
@ MSP430_CALL
Definition: msp430_disas.h:16
@ MSP430_SWPB
Definition: msp430_disas.h:12

References cmd, get_as(), get_dst(), get_oneop_opcode(), MSP430_CALL, MSP430_ONEOP, MSP430_PC, MSP430_PUSH, MSP430_R3, msp430_register_names, MSP430_RETI, MSP430_RRA, MSP430_RRC, MSP430_SR, MSP430_SWPB, MSP430_SXT, one_op_instrs, and snprintf.

Referenced by msp430_decode_command().

◆ decode_twoop_opcode()

static int decode_twoop_opcode ( ut16  instr,
ut16  op1,
ut16  op2,
struct msp430_cmd cmd 
)
static

Definition at line 309 of file msp430_disas.c.

309  {
310  ut8 opcode = get_twoop_opcode(instr);
311 
312  snprintf(cmd->instr, sizeof(cmd->instr), "%s", two_op_instrs[opcode]);
313  if (get_bw(instr)) {
314  strncat(cmd->instr, ".b", sizeof(cmd->instr) - 1 - strlen(cmd->instr));
315  }
316 
317  cmd->opcode = opcode;
318  return decode_addressing_mode(instr, op1, op2, cmd);
319 }
static const char * two_op_instrs[]
Definition: msp430_disas.c:31
static int decode_addressing_mode(ut16 instr, ut16 op1, ut16 op2, struct msp430_cmd *cmd)
Definition: msp430_disas.c:199

References cmd, decode_addressing_mode(), get_bw(), get_twoop_opcode(), snprintf, and two_op_instrs.

Referenced by msp430_decode_command().

◆ get_ad()

static ut8 get_ad ( ut16  instr)
static

Definition at line 79 of file msp430_disas.c.

79  {
80  return (instr >> 7) & 1;
81 }

Referenced by decode_addressing_mode(), and decode_emulation().

◆ get_as()

static ut8 get_as ( ut16  instr)
static

Definition at line 71 of file msp430_disas.c.

71  {
72  return (instr >> 4) & 3;
73 }

Referenced by decode_addressing_mode(), decode_emulation(), and decode_oneop_opcode().

◆ get_bw()

static ut8 get_bw ( ut16  instr)
static

Definition at line 75 of file msp430_disas.c.

75  {
76  return (instr >> 6) & 1;
77 }

Referenced by decode_emulation(), and decode_twoop_opcode().

◆ get_dst()

static int get_dst ( ut16  instr)
static

Definition at line 87 of file msp430_disas.c.

87  {
88  return instr & 0xF;
89 }

Referenced by decode_addressing_mode(), decode_emulation(), and decode_oneop_opcode().

◆ get_jmp_cond()

static ut8 get_jmp_cond ( ut16  instr)
static

Definition at line 325 of file msp430_disas.c.

325  {
326  return (instr >> 10) & 7;
327 }

Referenced by decode_jmp().

◆ get_jmp_opcode()

static ut8 get_jmp_opcode ( ut16  instr)
static

Definition at line 321 of file msp430_disas.c.

321  {
322  return instr >> 13;
323 }

Referenced by decode_jmp().

◆ get_oneop_opcode()

static int get_oneop_opcode ( ut16  instr)
static

Definition at line 345 of file msp430_disas.c.

345  {
346  return (instr >> 7) & 0x7;
347 }

Referenced by decode_oneop_opcode().

◆ get_src()

static int get_src ( ut16  instr)
static

Definition at line 83 of file msp430_disas.c.

83  {
84  return (instr >> 8) & 0xF;
85 }

Referenced by decode_addressing_mode(), and decode_emulation().

◆ get_twoop_opcode()

static ut8 get_twoop_opcode ( ut16  instr)
static

Definition at line 67 of file msp430_disas.c.

67  {
68  return instr >> 12;
69 }

Referenced by decode_emulation(), decode_twoop_opcode(), and msp430_decode_command().

◆ msp430_decode_command()

int msp430_decode_command ( const ut8 in,
int  len,
struct msp430_cmd cmd 
)

Definition at line 441 of file msp430_disas.c.

441  {
442  int ret = -1;
443  ut16 operand1 = 0, operand2 = 0;
444  if (len < 2) {
445  return -1;
446  }
447  ut16 instr = rz_read_le16(in);
448  ut8 opcode = get_twoop_opcode(instr);
449 
450  switch (opcode) {
452  // Invalid opcode.
453  break;
455  // Single operand instructions or invalid opcode.
456  if ((instr & 0x0f80) <= 0x0300) {
457  // Single operand instructions.
458  if (len >= 4) {
459  operand1 = rz_read_at_le16(in, 2);
460  }
461  ret = decode_oneop_opcode(instr, operand1, cmd);
462  }
463  break;
466  // Jumps.
467  decode_jmp(instr, cmd);
468  ret = 2;
469  break;
470  default:
471  // Double operand instructions.
472  cmd->type = MSP430_TWOOP;
473  if (len >= 4) {
474  operand1 = rz_read_at_le16(in, 2);
475  if (len >= 6) {
476  operand2 = rz_read_at_le16(in, 4);
477  }
478  }
479  ret = decode_twoop_opcode(instr, operand1, operand2, cmd);
480  break;
481  }
482 
483  /* if ret < 0, it's an invalid opcode.Say so and return 2 since
484  * all MSP430 opcodes are of 16 bits,valid or invalid */
485  if (ret < 0) {
486  cmd->type = MSP430_INV;
487  snprintf(cmd->instr, sizeof(cmd->instr), "invalid");
488  cmd->operands[0] = '\0';
489  ret = 2;
490  }
491 
492  return ret;
493 }
size_t len
Definition: 6502dis.c:15
const lzma_allocator const uint8_t * in
Definition: block.h:527
static void decode_jmp(ut16 instr, struct msp430_cmd *cmd)
Definition: msp430_disas.c:329
static int decode_oneop_opcode(ut16 instr, ut16 op, struct msp430_cmd *cmd)
Definition: msp430_disas.c:349
static int decode_twoop_opcode(ut16 instr, ut16 op1, ut16 op2, struct msp430_cmd *cmd)
Definition: msp430_disas.c:309
@ MSP430_INV
Definition: msp430_disas.h:59
@ MSP430_TWOOP
Definition: msp430_disas.h:57
static ut16 rz_read_at_le16(const void *src, size_t offset)
Definition: rz_endian.h:214
static ut16 rz_read_le16(const void *src)
Definition: rz_endian.h:206

References cmd, decode_jmp(), decode_oneop_opcode(), decode_twoop_opcode(), get_twoop_opcode(), in, len, MSP430_INV, MSP430_TWOOP, MSP430_TWOOP_OPCODE_INVALID, MSP430_TWOOP_OPCODE_JUMP2, MSP430_TWOOP_OPCODE_JUMP3, MSP430_TWOOP_OPCODE_SINGLEOP, rz_read_at_le16(), rz_read_le16(), and snprintf.

Referenced by disassemble(), and msp430_op().

◆ remove_first_operand()

static void remove_first_operand ( struct msp430_cmd cmd)
static

Definition at line 91 of file msp430_disas.c.

91  {
92  if (strchr(cmd->operands, ',')) {
93  memmove(cmd->operands, strchr(cmd->operands, ',') + 2,
94  strlen(strchr(cmd->operands, ',') + 2) + 1);
95  }
96 }

References cmd.

Referenced by decode_emulation().

◆ remove_second_operand()

static void remove_second_operand ( struct msp430_cmd cmd)
static

Definition at line 98 of file msp430_disas.c.

98  {
99  if (strchr(cmd->operands, ',')) {
100  {
101  *strchr(cmd->operands, ',') = '\0';
102  }
103  }
104 }

References cmd.

Referenced by decode_emulation().

Variable Documentation

◆ jmp_instrs

const char* jmp_instrs[]
static
Initial value:
= {
[MSP430_JEQ] = "jeq",
[MSP430_JNE] = "jnz",
[MSP430_JC] = "jc",
[MSP430_JNC] = "jnc",
[MSP430_JN] = "jn",
[MSP430_JGE] = "jge",
[MSP430_JL] = "jl",
[MSP430_JMP] = "jmp",
}
@ MSP430_JMP
Definition: msp430_disas.h:29
@ MSP430_JL
Definition: msp430_disas.h:28
@ MSP430_JEQ
Definition: msp430_disas.h:23
@ MSP430_JGE
Definition: msp430_disas.h:27
@ MSP430_JN
Definition: msp430_disas.h:26
@ MSP430_JNE
Definition: msp430_disas.h:22
@ MSP430_JC
Definition: msp430_disas.h:25
@ MSP430_JNC
Definition: msp430_disas.h:24

Definition at line 56 of file msp430_disas.c.

Referenced by decode_jmp().

◆ msp430_register_names

const char* msp430_register_names[]
static
Initial value:
= {
"pc",
"sp",
"sr",
"cg",
"r4",
"r5",
"r6",
"r7",
"r8",
"r9",
"r10",
"r11",
"r12",
"r13",
"r14",
"r15",
}

Definition at line 12 of file msp430_disas.c.

Referenced by decode_addressing_mode(), decode_emulation(), and decode_oneop_opcode().

◆ one_op_instrs

const char* one_op_instrs[]
static
Initial value:
= {
[MSP430_RRC] = "rrc",
[MSP430_SWPB] = "swpb",
[MSP430_RRA] = "rra",
[MSP430_SXT] = "sxt",
[MSP430_PUSH] = "push",
[MSP430_CALL] = "call",
[MSP430_RETI] = "reti",
}

Definition at line 46 of file msp430_disas.c.

Referenced by decode_oneop_opcode().

◆ two_op_instrs

const char* two_op_instrs[]
static
Initial value:
= {
[MSP430_MOV] = "mov",
[MSP430_ADD] = "add",
[MSP430_ADDC] = "addc",
[MSP430_SUBC] = "subc",
[MSP430_SUB] = "sub",
[MSP430_CMP] = "cmp",
[MSP430_DADD] = "dadd",
[MSP430_BIT] = "bit",
[MSP430_BIC] = "bic",
[MSP430_BIS] = "bis",
[MSP430_XOR] = "xor",
[MSP430_AND] = "and",
}
@ MSP430_BIT
Definition: msp430_disas.h:41
@ MSP430_AND
Definition: msp430_disas.h:45

Definition at line 31 of file msp430_disas.c.

Referenced by decode_twoop_opcode().