1 /* MSPDebug - debugging tool for the eZ430
2  * Copyright (C) 2009, 2010 Daniel Beer
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 
19 #include <assert.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <stdio.h>
23 #include <ctype.h>
24 
25 #include "dis.h"
26 #include "util.h"
27 
28 #define ALL_ONES               0xfffff
29 #define EXTENSION_BIT          0x20000
30 
31 /**********************************************************************/
32 /* Disassembler
33  */
34 
add_index(address_t reg_base,address_t index,int is_20bit)35 static address_t add_index(address_t reg_base, address_t index,
36 			   int is_20bit)
37 {
38 	return (reg_base + index) & (is_20bit ? 0xfffff : 0xffff);
39 }
40 
decode_00xx(const uint8_t * code,address_t len,struct msp430_instruction * insn)41 static int decode_00xx(const uint8_t *code, address_t len,
42 		       struct msp430_instruction *insn)
43 {
44 	uint16_t op = code[0] | (code[1] << 8);
45 	int subtype = (op >> 4) & 0xf;
46 	int have_arg = 0;
47 	address_t arg = 0;
48 
49 	/* Parameters common to most cases */
50 	insn->op = MSP430_OP_MOVA;
51 	insn->itype = MSP430_ITYPE_DOUBLE;
52 	insn->dsize = MSP430_DSIZE_AWORD;
53 	insn->dst_mode = MSP430_AMODE_REGISTER;
54 	insn->dst_reg = op & 0xf;
55 	insn->src_mode = MSP430_AMODE_REGISTER;
56 	insn->src_reg = (op >> 8) & 0xf;
57 
58 	if (len >= 4) {
59 		have_arg = 1;
60 		arg = code[2] | (code[3] << 8);
61 	}
62 
63 	switch (subtype) {
64 	case 0:
65 		insn->src_mode = MSP430_AMODE_INDIRECT;
66 		return 2;
67 
68 	case 1:
69 		insn->src_mode = MSP430_AMODE_INDIRECT_INC;
70 		return 2;
71 
72 	case 2:
73 		if (!have_arg)
74 			return -1;
75 		insn->src_mode = MSP430_AMODE_ABSOLUTE;
76 		insn->src_addr = ((op & 0xf00) << 8) | arg;
77 		return 4;
78 
79 	case 3:
80 		if (!have_arg)
81 			return -1;
82 		insn->src_mode = MSP430_AMODE_INDEXED;
83 		insn->src_addr = arg;
84 		return 4;
85 
86 	case 4:
87 	case 5:
88 		/* RxxM */
89 		insn->itype = MSP430_ITYPE_DOUBLE;
90 		insn->op = op & 0xf3e0;
91 		insn->dst_mode = MSP430_AMODE_REGISTER;
92 		insn->dst_reg = op & 0xf;
93 		insn->src_mode = MSP430_AMODE_IMMEDIATE;
94 		insn->src_addr = 1 + ((op >> 10) & 3);
95 		insn->dsize = (op & 0x0010) ?
96 			MSP430_DSIZE_WORD : MSP430_DSIZE_AWORD;
97 		return 2;
98 
99 	case 6:
100 		if (!have_arg)
101 			return -1;
102 
103 		insn->dst_mode = MSP430_AMODE_ABSOLUTE;
104 		insn->dst_addr = ((op & 0xf) << 16) | arg;
105 		return 4;
106 
107 	case 7:
108 		if (!have_arg)
109 			return -1;
110 		insn->dst_mode = MSP430_AMODE_INDEXED;
111 		insn->dst_addr = arg;
112 		return 4;
113 
114 	case 8:
115 		if (!have_arg)
116 			return -1;
117 		insn->src_mode = MSP430_AMODE_IMMEDIATE;
118 		insn->src_addr = ((op & 0xf00) << 8) | arg;
119 		return 4;
120 
121 	case 9:
122 		if (!have_arg)
123 			return -1;
124 		insn->op = MSP430_OP_CMPA;
125 		insn->src_mode = MSP430_AMODE_IMMEDIATE;
126 		insn->src_addr = ((op & 0xf00) << 8) | arg;
127 		return 4;
128 
129 	case 10:
130 		if (!have_arg)
131 			return -1;
132 		insn->op = MSP430_OP_ADDA;
133 		insn->src_mode = MSP430_AMODE_IMMEDIATE;
134 		insn->src_addr = ((op & 0xf00) << 8) | arg;
135 		return 4;
136 
137 	case 11:
138 		if (!have_arg)
139 			return -1;
140 		insn->op = MSP430_OP_SUBA;
141 		insn->src_mode = MSP430_AMODE_IMMEDIATE;
142 		insn->src_addr = ((op & 0xf00) << 8) | arg;
143 		return 4;
144 
145 	case 12:
146 		return 2;
147 
148 	case 13:
149 		insn->op = MSP430_OP_CMPA;
150 		return 2;
151 
152 	case 14:
153 		insn->op = MSP430_OP_ADDA;
154 		return 2;
155 
156 	case 15:
157 		insn->op = MSP430_OP_SUBA;
158 		return 2;
159 	}
160 
161 	return -1;
162 }
163 
decode_13xx(const uint8_t * code,address_t len,struct msp430_instruction * insn)164 static int decode_13xx(const uint8_t *code, address_t len,
165 		       struct msp430_instruction *insn)
166 {
167 	uint16_t op = code[0] | (code[1] << 8);
168 	int subtype = (op >> 4) & 0xf;
169 
170 	insn->itype = MSP430_ITYPE_SINGLE;
171 	insn->op = MSP430_OP_CALLA;
172 
173 	switch (subtype) {
174 	case 0:
175 		insn->itype = MSP430_ITYPE_NOARG;
176 		insn->op = MSP430_OP_RETI;
177 		return 2;
178 
179 	case 4:
180 		insn->dst_mode = MSP430_AMODE_REGISTER;
181 		insn->dst_reg = op & 0xf;
182 		return 2;
183 
184 	case 5:
185 		insn->dst_mode = MSP430_AMODE_INDEXED;
186 		insn->dst_reg = op & 0xf;
187 		break;
188 
189 	case 6:
190 		insn->dst_mode = MSP430_AMODE_INDIRECT;
191 		insn->dst_reg = op & 0xf;
192 		return 2;
193 
194 	case 7:
195 		insn->dst_mode = MSP430_AMODE_INDIRECT_INC;
196 		insn->dst_reg = op & 0xf;
197 		return 2;
198 
199 	case 8:
200 		insn->dst_mode = MSP430_AMODE_ABSOLUTE;
201 		insn->dst_addr = (address_t)(op & 0xf) << 16;
202 		break;
203 
204 	case 9:
205 		insn->dst_mode = MSP430_AMODE_SYMBOLIC;
206 		insn->dst_addr = (address_t)(op & 0xf) << 16;
207 		break;
208 
209 	case 11:
210 		insn->dst_mode = MSP430_AMODE_IMMEDIATE;
211 		insn->dst_addr = (address_t)(op & 0xf) << 16;
212 		break;
213 
214 	default:
215 		return -1;
216 	}
217 
218 	if (len < 4)
219 		return -1;
220 
221 	insn->dsize = MSP430_DSIZE_AWORD;
222 	insn->dst_addr |= code[2];
223 	insn->dst_addr |= code[3] << 8;
224 
225 	return 4;
226 }
227 
decode_14xx(const uint8_t * code,struct msp430_instruction * insn)228 static int decode_14xx(const uint8_t *code,
229 		       struct msp430_instruction *insn)
230 {
231 	uint16_t op = (code[1] << 8) | code[0];
232 
233 	/* PUSHM/POPM */
234 	insn->itype = MSP430_ITYPE_DOUBLE;
235 	insn->op = op & 0xfe00;
236 	insn->dst_mode = MSP430_AMODE_REGISTER;
237 	insn->dst_reg = op & 0xf;
238 	insn->src_mode = MSP430_AMODE_IMMEDIATE;
239 	insn->src_addr = 1 + ((op >> 4) & 0xf);
240 	insn->dsize = (op & 0x0100) ?
241 		MSP430_DSIZE_WORD : MSP430_DSIZE_AWORD;
242 
243 	return 2;
244 }
245 
246 /* Decode a single-operand instruction.
247  *
248  * Returns the number of bytes consumed in decoding, or -1 if the a
249  * valid single-operand instruction could not be found.
250  */
decode_single(const uint8_t * code,address_t offset,address_t size,struct msp430_instruction * insn)251 static int decode_single(const uint8_t *code, address_t offset,
252 			 address_t size, struct msp430_instruction *insn)
253 {
254 	uint16_t op = (code[1] << 8) | code[0];
255 	int need_arg = 0;
256 
257 	insn->itype = MSP430_ITYPE_SINGLE;
258 	insn->op = op & 0xff80;
259 	insn->dsize = (op & 0x0040) ? MSP430_DSIZE_BYTE : MSP430_DSIZE_WORD;
260 
261 	insn->dst_mode = (op >> 4) & 0x3;
262 	insn->dst_reg = op & 0xf;
263 
264 	switch (insn->dst_mode) {
265 	case MSP430_AMODE_REGISTER: break;
266 
267 	case MSP430_AMODE_INDEXED:
268 		need_arg = 1;
269 		if (insn->dst_reg == MSP430_REG_PC) {
270 			insn->dst_addr = offset + 4;
271 			insn->dst_mode = MSP430_AMODE_SYMBOLIC;
272 		} else if (insn->dst_reg == MSP430_REG_SR) {
273 			insn->dst_mode = MSP430_AMODE_ABSOLUTE;
274 		} else if (insn->dst_reg == MSP430_REG_R3) {
275 			need_arg = 0; /* constant generator: #1 */
276 		}
277 		break;
278 
279 	case MSP430_AMODE_INDIRECT: break;
280 
281 	case MSP430_AMODE_INDIRECT_INC:
282 		if (insn->dst_reg == MSP430_REG_PC) {
283 			insn->dst_mode = MSP430_AMODE_IMMEDIATE;
284 			need_arg = 1;
285 		}
286 		break;
287 
288 	default: break;
289 	}
290 
291 	if (need_arg) {
292 		if (size < 4)
293 			return -1;
294 
295 		insn->dst_addr = add_index(insn->dst_addr,
296 			(code[3] << 8) | code[2], 0);
297 		return 4;
298 	}
299 
300 	return 2;
301 }
302 
303 /* Decode a double-operand instruction.
304  *
305  * Returns the number of bytes consumed or -1 if a valid instruction
306  * could not be found.
307  */
decode_double(const uint8_t * code,address_t offset,address_t size,struct msp430_instruction * insn,uint16_t ex_word)308 static int decode_double(const uint8_t *code, address_t offset,
309 			 address_t size, struct msp430_instruction *insn,
310 			 uint16_t ex_word)
311 {
312 	uint16_t op = (code[1] << 8) | code[0];
313 	int need_src = 0;
314 	int need_dst = 0;
315 	int ret = 2;
316 
317 	/* Decode and consume opcode */
318 	insn->itype = MSP430_ITYPE_DOUBLE;
319 	insn->op = op & 0xf000;
320 	insn->dsize = (op & 0x0040) ? MSP430_DSIZE_BYTE : MSP430_DSIZE_WORD;
321 
322 	insn->src_mode = (op >> 4) & 0x3;
323 	insn->src_reg = (op >> 8) & 0xf;
324 
325 	insn->dst_mode = (op >> 7) & 0x1;
326 	insn->dst_reg = op & 0xf;
327 
328 	offset += 2;
329 	code += 2;
330 	size -= 2;
331 
332 	/* Decode and consume source operand */
333 	switch (insn->src_mode) {
334 	case MSP430_AMODE_REGISTER: break;
335 	case MSP430_AMODE_INDEXED:
336 		need_src = 1;
337 
338 		if (insn->src_reg == MSP430_REG_PC) {
339 			insn->src_mode = MSP430_AMODE_SYMBOLIC;
340 			insn->src_addr = offset;
341 		} else if (insn->src_reg == MSP430_REG_SR)
342 			insn->src_mode = MSP430_AMODE_ABSOLUTE;
343 		else if (insn->src_reg == MSP430_REG_R3)
344 			need_src = 0;
345 		break;
346 
347 	case MSP430_AMODE_INDIRECT: break;
348 
349 	case MSP430_AMODE_INDIRECT_INC:
350 		if (insn->src_reg == MSP430_REG_PC) {
351 			insn->src_mode = MSP430_AMODE_IMMEDIATE;
352 			need_src = 1;
353 		}
354 		break;
355 
356 	default: break;
357 	}
358 
359 	if (need_src) {
360 		if (size < 2)
361 			return -1;
362 
363 		insn->src_addr = add_index(insn->src_addr,
364 			((ex_word << 9) & 0xf0000) |
365 			((code[1] << 8) | code[0]),
366 			ex_word);
367 		offset += 2;
368 		code += 2;
369 		size -= 2;
370 		ret += 2;
371 	}
372 
373 	/* Decode and consume destination operand */
374 	switch (insn->dst_mode) {
375 	case MSP430_AMODE_REGISTER: break;
376 	case MSP430_AMODE_INDEXED:
377 		need_dst = 1;
378 
379 		if (insn->dst_reg == MSP430_REG_PC) {
380 			insn->dst_mode = MSP430_AMODE_SYMBOLIC;
381 			insn->dst_addr = offset;
382 		} else if (insn->dst_reg == MSP430_REG_SR)
383 			insn->dst_mode = MSP430_AMODE_ABSOLUTE;
384 		break;
385 
386 	default: break;
387 	}
388 
389 	if (need_dst) {
390 		if (size < 2)
391 			return -1;
392 
393 		insn->dst_addr = add_index(insn->dst_addr,
394 			((ex_word << 16) & 0xf0000) |
395 			(code[1] << 8) | code[0],
396 			ex_word);
397 		ret += 2;
398 	}
399 
400 	return ret;
401 }
402 
403 /* Decode a jump instruction.
404  *
405  * All jump instructions are one word in length, so this function
406  * always returns 2 (to indicate the consumption of 2 bytes).
407  */
decode_jump(const uint8_t * code,address_t offset,struct msp430_instruction * insn)408 static int decode_jump(const uint8_t *code, address_t offset,
409 		       struct msp430_instruction *insn)
410 {
411 	uint16_t op = (code[1] << 8) | code[0];
412 	int tgtrel = op & 0x3ff;
413 
414 	if (tgtrel & 0x200)
415 		tgtrel -= 0x400;
416 
417 	insn->op = op & 0xfc00;
418 	insn->itype = MSP430_ITYPE_JUMP;
419 	insn->dst_addr = offset + 2 + tgtrel * 2;
420 	insn->dst_mode = MSP430_AMODE_SYMBOLIC;
421 	insn->dst_reg = MSP430_REG_PC;
422 
423 	return 2;
424 }
425 
remap_cgen(msp430_amode_t * mode,address_t * addr,msp430_reg_t * reg)426 static void remap_cgen(msp430_amode_t *mode,
427 		       address_t *addr,
428 		       msp430_reg_t *reg)
429 {
430 	if (*reg == MSP430_REG_SR) {
431 		if (*mode == MSP430_AMODE_INDIRECT) {
432 			*mode = MSP430_AMODE_IMMEDIATE;
433 			*addr = 4;
434 		} else if (*mode == MSP430_AMODE_INDIRECT_INC) {
435 			*mode = MSP430_AMODE_IMMEDIATE;
436 			*addr = 8;
437 		}
438 	} else if (*reg == MSP430_REG_R3) {
439 		if (*mode == MSP430_AMODE_REGISTER)
440 			*addr = 0;
441 		else if (*mode == MSP430_AMODE_INDEXED)
442 			*addr = 1;
443 		else if (*mode == MSP430_AMODE_INDIRECT)
444 			*addr = 2;
445 		else if (*mode == MSP430_AMODE_INDIRECT_INC)
446 			*addr = ALL_ONES;
447 
448 		*mode = MSP430_AMODE_IMMEDIATE;
449 	}
450 }
451 
452 /* Take a decoded instruction and replace certain addressing modes of
453  * the constant generator registers with their corresponding immediate
454  * values.
455  */
find_cgens(struct msp430_instruction * insn)456 static void find_cgens(struct msp430_instruction *insn)
457 {
458 	if (insn->itype == MSP430_ITYPE_DOUBLE)
459 		remap_cgen(&insn->src_mode, &insn->src_addr,
460 			   &insn->src_reg);
461 	else if (insn->itype == MSP430_ITYPE_SINGLE)
462 		remap_cgen(&insn->dst_mode, &insn->dst_addr,
463 			   &insn->dst_reg);
464 }
465 
466 /* Recognise special cases of real instructions and translate them to
467  * emulated instructions.
468  */
find_emulated_ops(struct msp430_instruction * insn)469 static void find_emulated_ops(struct msp430_instruction *insn)
470 {
471 	switch (insn->op) {
472 	case MSP430_OP_ADD:
473 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE) {
474 			if (insn->src_addr == 1) {
475 				insn->op = MSP430_OP_INC;
476 				insn->itype = MSP430_ITYPE_SINGLE;
477 			} else if (insn->src_addr == 2) {
478 				insn->op = MSP430_OP_INCD;
479 				insn->itype = MSP430_ITYPE_SINGLE;
480 			}
481 		} else if (insn->dst_mode == insn->src_mode &&
482 			   insn->dst_reg == insn->src_reg &&
483 			   insn->dst_addr == insn->src_addr) {
484 			insn->op = MSP430_OP_RLA;
485 			insn->itype = MSP430_ITYPE_SINGLE;
486 		}
487 		break;
488 
489 	case MSP430_OP_ADDA:
490 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
491 		    insn->src_addr == 2) {
492 			insn->op = MSP430_OP_INCDA;
493 			insn->itype = MSP430_ITYPE_SINGLE;
494 		}
495 		break;
496 
497 	case MSP430_OP_ADDX:
498 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE) {
499 			if (insn->src_addr == 1) {
500 				insn->op = MSP430_OP_INCX;
501 				insn->itype = MSP430_ITYPE_SINGLE;
502 			} else if (insn->src_addr == 2) {
503 				insn->op = MSP430_OP_INCDX;
504 				insn->itype = MSP430_ITYPE_SINGLE;
505 			}
506 		} else if (insn->dst_mode == insn->src_mode &&
507 			   insn->dst_reg == insn->src_reg &&
508 			   insn->dst_addr == insn->src_addr) {
509 			insn->op = MSP430_OP_RLAX;
510 			insn->itype = MSP430_ITYPE_SINGLE;
511 		}
512 		break;
513 
514 	case MSP430_OP_ADDC:
515 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
516 		    !insn->src_addr) {
517 			insn->op = MSP430_OP_ADC;
518 			insn->itype = MSP430_ITYPE_SINGLE;
519 		} else if (insn->dst_mode == insn->src_mode &&
520 			   insn->dst_reg == insn->src_reg &&
521 			   insn->dst_addr == insn->src_addr) {
522 			insn->op = MSP430_OP_RLC;
523 			insn->itype = MSP430_ITYPE_SINGLE;
524 		}
525 		break;
526 
527 	case MSP430_OP_ADDCX:
528 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
529 		    !insn->src_addr) {
530 			insn->op = MSP430_OP_ADCX;
531 			insn->itype = MSP430_ITYPE_SINGLE;
532 		} else if (insn->dst_mode == insn->src_mode &&
533 			   insn->dst_reg == insn->src_reg &&
534 			   insn->dst_addr == insn->src_addr) {
535 			insn->op = MSP430_OP_RLCX;
536 			insn->itype = MSP430_ITYPE_SINGLE;
537 		}
538 		break;
539 
540 	case MSP430_OP_BIC:
541 		if (insn->dst_mode == MSP430_AMODE_REGISTER &&
542 		    insn->dst_reg == MSP430_REG_SR &&
543 		    insn->src_mode == MSP430_AMODE_IMMEDIATE) {
544 			if (insn->src_addr == 1) {
545 				insn->op = MSP430_OP_CLRC;
546 				insn->itype = MSP430_ITYPE_NOARG;
547 			} else if (insn->src_addr == 4) {
548 				insn->op = MSP430_OP_CLRN;
549 				insn->itype = MSP430_ITYPE_NOARG;
550 			} else if (insn->src_addr == 2) {
551 				insn->op = MSP430_OP_CLRZ;
552 				insn->itype = MSP430_ITYPE_NOARG;
553 			} else if (insn->src_addr == 8) {
554 				insn->op = MSP430_OP_DINT;
555 				insn->itype = MSP430_ITYPE_NOARG;
556 			}
557 		}
558 		break;
559 
560 	case MSP430_OP_BIS:
561 		if (insn->dst_mode == MSP430_AMODE_REGISTER &&
562 		    insn->dst_reg == MSP430_REG_SR &&
563 		    insn->src_mode == MSP430_AMODE_IMMEDIATE) {
564 			if (insn->src_addr == 1) {
565 				insn->op = MSP430_OP_SETC;
566 				insn->itype = MSP430_ITYPE_NOARG;
567 			} else if (insn->src_addr == 4) {
568 				insn->op = MSP430_OP_SETN;
569 				insn->itype = MSP430_ITYPE_NOARG;
570 			} else if (insn->src_addr == 2) {
571 				insn->op = MSP430_OP_SETZ;
572 				insn->itype = MSP430_ITYPE_NOARG;
573 			} else if (insn->src_addr == 8) {
574 				insn->op = MSP430_OP_EINT;
575 				insn->itype = MSP430_ITYPE_NOARG;
576 			}
577 		}
578 		break;
579 
580 	case MSP430_OP_CMP:
581 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
582 		    !insn->src_addr) {
583 			insn->op = MSP430_OP_TST;
584 			insn->itype = MSP430_ITYPE_SINGLE;
585 		}
586 		break;
587 
588 	case MSP430_OP_CMPA:
589 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
590 		    !insn->src_addr) {
591 			insn->op = MSP430_OP_TSTA;
592 			insn->itype = MSP430_ITYPE_SINGLE;
593 		}
594 		break;
595 
596 	case MSP430_OP_CMPX:
597 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
598 		    !insn->src_addr) {
599 			insn->op = MSP430_OP_TSTX;
600 			insn->itype = MSP430_ITYPE_SINGLE;
601 		}
602 		break;
603 
604 	case MSP430_OP_DADD:
605 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
606 		    !insn->src_addr) {
607 			insn->op = MSP430_OP_DADC;
608 			insn->itype = MSP430_ITYPE_SINGLE;
609 		}
610 		break;
611 
612 	case MSP430_OP_DADDX:
613 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
614 		    !insn->src_addr) {
615 			insn->op = MSP430_OP_DADCX;
616 			insn->itype = MSP430_ITYPE_SINGLE;
617 		}
618 		break;
619 
620 	case MSP430_OP_MOV:
621 		if (insn->src_mode == MSP430_AMODE_INDIRECT_INC &&
622 		    insn->src_reg == MSP430_REG_SP) {
623 			if (insn->dst_mode == MSP430_AMODE_REGISTER &&
624 			    insn->dst_reg == MSP430_REG_PC) {
625 				insn->op = MSP430_OP_RET;
626 				insn->itype = MSP430_ITYPE_NOARG;
627 			} else {
628 				insn->op = MSP430_OP_POP;
629 				insn->itype = MSP430_ITYPE_SINGLE;
630 			}
631 		} else if (insn->dst_mode == MSP430_AMODE_REGISTER &&
632 			   insn->dst_reg == MSP430_REG_PC) {
633 			insn->op = MSP430_OP_BR;
634 			insn->itype = MSP430_ITYPE_SINGLE;
635 			insn->dst_mode = insn->src_mode;
636 			insn->dst_reg = insn->src_reg;
637 			insn->dst_addr = insn->src_addr;
638 		} else if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
639 			   !insn->src_addr) {
640 			if (insn->dst_mode == MSP430_AMODE_REGISTER &&
641 			    insn->dst_reg == MSP430_REG_R3) {
642 				insn->op = MSP430_OP_NOP;
643 				insn->itype = MSP430_ITYPE_NOARG;
644 			} else {
645 				insn->op = MSP430_OP_CLR;
646 				insn->itype = MSP430_ITYPE_SINGLE;
647 			}
648 		}
649 		break;
650 
651 	case MSP430_OP_MOVA:
652 		if (insn->src_mode == MSP430_AMODE_INDIRECT_INC &&
653 		    insn->src_reg == MSP430_REG_SP) {
654 			if (insn->dst_mode == MSP430_AMODE_REGISTER &&
655 			    insn->dst_reg == MSP430_REG_PC) {
656 				insn->op = MSP430_OP_RETA;
657 				insn->itype = MSP430_ITYPE_NOARG;
658 			} else {
659 				insn->op = MSP430_OP_POPX;
660 				insn->itype = MSP430_ITYPE_SINGLE;
661 			}
662 		} else if (insn->dst_mode == MSP430_AMODE_REGISTER &&
663 			   insn->dst_reg == MSP430_REG_PC) {
664 			insn->op = MSP430_OP_BRA;
665 			insn->itype = MSP430_ITYPE_SINGLE;
666 			insn->dst_mode = insn->src_mode;
667 			insn->dst_reg = insn->src_reg;
668 			insn->dst_addr = insn->src_addr;
669 		} else if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
670 			   !insn->src_addr) {
671 			if (insn->dst_mode == MSP430_AMODE_REGISTER &&
672 			    insn->dst_reg == MSP430_REG_R3) {
673 				insn->op = MSP430_OP_NOP;
674 				insn->itype = MSP430_ITYPE_NOARG;
675 			} else {
676 				insn->op = MSP430_OP_CLRX;
677 				insn->itype = MSP430_ITYPE_SINGLE;
678 			}
679 		}
680 		break;
681 
682 	case MSP430_OP_SUB:
683 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE) {
684 			if (insn->src_addr == 1) {
685 				insn->op = MSP430_OP_DEC;
686 				insn->itype = MSP430_ITYPE_SINGLE;
687 			} else if (insn->src_addr == 2) {
688 				insn->op = MSP430_OP_DECD;
689 				insn->itype = MSP430_ITYPE_SINGLE;
690 			}
691 		}
692 		break;
693 
694 	case MSP430_OP_SUBA:
695 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
696 		    insn->src_addr == 2) {
697 			insn->op = MSP430_OP_DECDA;
698 			insn->itype = MSP430_ITYPE_SINGLE;
699 		}
700 		break;
701 
702 	case MSP430_OP_SUBX:
703 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE) {
704 			if (insn->src_addr == 1) {
705 				insn->op = MSP430_OP_DECX;
706 				insn->itype = MSP430_ITYPE_SINGLE;
707 			} else if (insn->src_addr == 2) {
708 				insn->op = MSP430_OP_DECDX;
709 				insn->itype = MSP430_ITYPE_SINGLE;
710 			}
711 		}
712 		break;
713 
714 	case MSP430_OP_SUBC:
715 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
716 		    !insn->src_addr) {
717 			insn->op = MSP430_OP_SBC;
718 			insn->itype = MSP430_ITYPE_SINGLE;
719 		}
720 		break;
721 
722 	case MSP430_OP_SUBCX:
723 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
724 		    !insn->src_addr) {
725 			insn->op = MSP430_OP_SECX;
726 			insn->itype = MSP430_ITYPE_SINGLE;
727 		}
728 		break;
729 
730 	case MSP430_OP_XOR:
731 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
732 		    insn->src_addr == ALL_ONES) {
733 			insn->op = MSP430_OP_INV;
734 			insn->itype = MSP430_ITYPE_SINGLE;
735 		}
736 		break;
737 
738 	case MSP430_OP_XORX:
739 		if (insn->src_mode == MSP430_AMODE_IMMEDIATE &&
740 		    insn->src_addr == ALL_ONES) {
741 			insn->op = MSP430_OP_INVX;
742 			insn->itype = MSP430_ITYPE_SINGLE;
743 		}
744 		break;
745 
746 	default: break;
747 	}
748 }
749 
750 /* Decode a single instruction.
751  *
752  * Returns the number of bytes consumed, or -1 if an error occured.
753  *
754  * The caller needs to pass a pointer to the bytes to be decoded, the
755  * virtual offset of those bytes, and the maximum number available. If
756  * successful, the decoded instruction is written into the structure
757  * pointed to by insn.
758  */
dis_decode(const uint8_t * code,address_t offset,address_t len,struct msp430_instruction * insn)759 int dis_decode(const uint8_t *code, address_t offset, address_t len,
760 	       struct msp430_instruction *insn)
761 {
762 	uint16_t op;
763 	uint16_t ex_word = 0;
764 	int ret;
765 	address_t ds_mask = ALL_ONES;
766 
767 	memset(insn, 0, sizeof(*insn));
768 	insn->offset = offset;
769 
770 	/* Perform decoding */
771 	if (len < 2)
772 		return -1;
773 	op = (code[1] << 8) | code[0];
774 
775 	if ((op & 0xf800) == 0x1800) {
776 		ex_word = op;
777 		code += 2;
778 		offset += 2;
779 		len -= 2;
780 
781 		if (len < 2)
782 			return -1;
783 		op = (code[1] << 8) | code[0];
784 
785 		if ((op & 0xf000) >= 0x4000)
786 			ret = decode_double(code, offset, len, insn, ex_word);
787 		else if ((op & 0xf000) == 0x1000 && (op & 0xfc00) < 0x1280)
788 			ret = decode_single(code, offset, len, insn);
789 		else
790 			return -1;
791 
792 		insn->op |= EXTENSION_BIT;
793 		ret += 2;
794 
795 		if (insn->dst_mode == MSP430_AMODE_REGISTER &&
796 		    (insn->itype == MSP430_ITYPE_SINGLE ||
797 		     insn->src_mode == MSP430_AMODE_REGISTER)) {
798 			if ((ex_word >> 8) & 1) {
799 				if (insn->op != MSP430_OP_RRCX)
800 					return -1;
801 				insn->op = MSP430_OP_RRUX;
802 			}
803 			insn->rep_register = (ex_word >> 7) & 1;
804 			insn->rep_index = ex_word & 0xf;
805 		}
806 
807 		if (!(ex_word & 0x40))
808 			insn->dsize |= 2;
809 	} else {
810 		if ((op & 0xf000) == 0x0000)
811 			ret = decode_00xx(code, len, insn);
812 		else if ((op & 0xfc00) == 0x1400)
813 			ret = decode_14xx(code, insn);
814 		else if ((op & 0xff00) == 0x1300)
815 			ret = decode_13xx(code, len, insn);
816 		else if ((op & 0xf000) == 0x1000)
817 			ret = decode_single(code, offset, len, insn);
818 		else if ((op & 0xf000) >= 0x2000 && (op & 0xf000) < 0x4000)
819 			ret = decode_jump(code, offset, insn);
820 		else if ((op & 0xf000) >= 0x4000)
821 			ret = decode_double(code, offset, len, insn, 0);
822 		else
823 			return -1;
824 	}
825 
826 	/* Interpret "emulated" instructions, constant generation, and
827 	 * trim data sizes.
828 	 */
829 	find_cgens(insn);
830 	find_emulated_ops(insn);
831 
832 	if (insn->dsize == MSP430_DSIZE_BYTE)
833 		ds_mask = 0xff;
834 	else if (insn->dsize == MSP430_DSIZE_WORD)
835 		ds_mask = 0xffff;
836 
837 	if (insn->src_mode == MSP430_AMODE_IMMEDIATE)
838 		insn->src_addr &= ds_mask;
839 	if (insn->dst_mode == MSP430_AMODE_IMMEDIATE)
840 		insn->dst_addr &= ds_mask;
841 
842 	insn->len = ret;
843 	return ret;
844 }
845 
846 static const struct {
847 	msp430_op_t     op;
848 	const char      *mnemonic;
849 } opcode_names[] = {
850 	/* Single operand */
851 	{MSP430_OP_RRC,         "RRC"},
852 	{MSP430_OP_SWPB,        "SWPB"},
853 	{MSP430_OP_RRA,         "RRA"},
854 	{MSP430_OP_SXT,         "SXT"},
855 	{MSP430_OP_PUSH,        "PUSH"},
856 	{MSP430_OP_CALL,        "CALL"},
857 	{MSP430_OP_RETI,        "RETI"},
858 
859 	/* Jump */
860 	{MSP430_OP_JNZ,         "JNZ"},
861 	{MSP430_OP_JZ,          "JZ"},
862 	{MSP430_OP_JNC,         "JNC"},
863 	{MSP430_OP_JC,          "JC"},
864 	{MSP430_OP_JN,          "JN"},
865 	{MSP430_OP_JL,          "JL"},
866 	{MSP430_OP_JGE,         "JGE"},
867 	{MSP430_OP_JMP,         "JMP"},
868 
869 	/* Double operand */
870 	{MSP430_OP_MOV,         "MOV"},
871 	{MSP430_OP_ADD,         "ADD"},
872 	{MSP430_OP_ADDC,        "ADDC"},
873 	{MSP430_OP_SUBC,        "SUBC"},
874 	{MSP430_OP_SUB,         "SUB"},
875 	{MSP430_OP_CMP,         "CMP"},
876 	{MSP430_OP_DADD,        "DADD"},
877 	{MSP430_OP_BIT,         "BIT"},
878 	{MSP430_OP_BIC,         "BIC"},
879 	{MSP430_OP_BIS,         "BIS"},
880 	{MSP430_OP_XOR,         "XOR"},
881 	{MSP430_OP_AND,         "AND"},
882 
883 	/* Emulated instructions */
884 	{MSP430_OP_ADC,         "ADC"},
885 	{MSP430_OP_BR,          "BR"},
886 	{MSP430_OP_CLR,         "CLR"},
887 	{MSP430_OP_CLRC,        "CLRC"},
888 	{MSP430_OP_CLRN,        "CLRN"},
889 	{MSP430_OP_CLRZ,        "CLRZ"},
890 	{MSP430_OP_DADC,        "DADC"},
891 	{MSP430_OP_DEC,         "DEC"},
892 	{MSP430_OP_DECD,        "DECD"},
893 	{MSP430_OP_DINT,        "DINT"},
894 	{MSP430_OP_EINT,        "EINT"},
895 	{MSP430_OP_INC,         "INC"},
896 	{MSP430_OP_INCD,        "INCD"},
897 	{MSP430_OP_INV,         "INV"},
898 	{MSP430_OP_NOP,         "NOP"},
899 	{MSP430_OP_POP,         "POP"},
900 	{MSP430_OP_RET,         "RET"},
901 	{MSP430_OP_RLA,         "RLA"},
902 	{MSP430_OP_RLC,         "RLC"},
903 	{MSP430_OP_SBC,         "SBC"},
904 	{MSP430_OP_SETC,        "SETC"},
905 	{MSP430_OP_SETN,        "SETN"},
906 	{MSP430_OP_SETZ,        "SETZ"},
907 	{MSP430_OP_TST,         "TST"},
908 
909 	/* MSP430X double operand (extension word) */
910 	{MSP430_OP_MOVX,        "MOVX"},
911 	{MSP430_OP_ADDX,        "ADDX"},
912 	{MSP430_OP_ADDCX,       "ADDCX"},
913 	{MSP430_OP_SUBCX,       "SUBCX"},
914 	{MSP430_OP_SUBX,        "SUBX"},
915 	{MSP430_OP_CMPX,        "CMPX"},
916 	{MSP430_OP_DADDX,       "DADDX"},
917 	{MSP430_OP_BITX,        "BITX"},
918 	{MSP430_OP_BICX,        "BICX"},
919 	{MSP430_OP_BISX,        "BISX"},
920 	{MSP430_OP_XORX,        "XORX"},
921 	{MSP430_OP_ANDX,        "ANDX"},
922 
923 	/* MSP430X single operand (extension word) */
924 	{MSP430_OP_RRCX,        "RRCX"},
925 	{MSP430_OP_RRUX,        "RRUX"},
926 	{MSP430_OP_SWPBX,       "SWPBX"},
927 	{MSP430_OP_RRAX,        "RRAX"},
928 	{MSP430_OP_SXTX,        "SXTX"},
929 	{MSP430_OP_PUSHX,       "PUSHX"},
930 
931 	/* MSP430X group 13xx */
932 	{MSP430_OP_CALLA,	"CALLA"},
933 
934 	/* MSP430X group 14xx */
935 	{MSP430_OP_PUSHM,	"PUSHM"},
936 	{MSP430_OP_POPM,	"POPM"},
937 
938 	/* MSP430X address instructions */
939 	{MSP430_OP_MOVA,        "MOVA"},
940 	{MSP430_OP_CMPA,        "CMPA"},
941 	{MSP430_OP_SUBA,	"SUBA"},
942 	{MSP430_OP_ADDA,	"ADDA"},
943 
944 	/* MSP430X group 00xx, non-address */
945 	{MSP430_OP_RRCM,        "RRCM"},
946 	{MSP430_OP_RRAM,        "RRAM"},
947 	{MSP430_OP_RLAM,	"RLAM"},
948 	{MSP430_OP_RRUM,	"RRUM"},
949 
950 	/* MSP430X emulated instructions */
951 	{MSP430_OP_ADCX,	"ADCX"},
952 	{MSP430_OP_BRA,		"BRA"},
953 	{MSP430_OP_RETA,	"RETA"},
954 	{MSP430_OP_CLRX,	"CLRX"},
955 	{MSP430_OP_DADCX,	"DADCX"},
956 	{MSP430_OP_DECX,	"DECX"},
957 	{MSP430_OP_DECDA,	"DECDA"},
958 	{MSP430_OP_DECDX,	"DECDX"},
959 	{MSP430_OP_INCX,	"INCX"},
960 	{MSP430_OP_INCDA,	"INCDA"},
961 	{MSP430_OP_INVX,	"INVX"},
962 	{MSP430_OP_RLAX,	"RLAX"},
963 	{MSP430_OP_RLCX,	"RLCX"},
964 	{MSP430_OP_SECX,	"SECX"},
965 	{MSP430_OP_TSTA,	"TSTA"},
966 	{MSP430_OP_TSTX,	"TSTX"},
967 	{MSP430_OP_POPX,	"POPX"},
968 	{MSP430_OP_INCDX,	"INCDX"}
969 };
970 
971 /* Return the mnemonic for an operation, if possible. */
dis_opcode_name(msp430_op_t op)972 const char *dis_opcode_name(msp430_op_t op)
973 {
974 	int i;
975 
976 	for (i = 0; i < ARRAY_LEN(opcode_names); i++)
977 		if (op == opcode_names[i].op)
978 			return opcode_names[i].mnemonic;
979 
980 	return NULL;
981 }
982 
dis_opcode_from_name(const char * name)983 int dis_opcode_from_name(const char *name)
984 {
985 	int i;
986 
987 	for (i = 0; i < ARRAY_LEN(opcode_names); i++)
988 		if (!strcasecmp(name, opcode_names[i].mnemonic))
989 			return opcode_names[i].op;
990 
991 	return -1;
992 }
993 
994 static const char *const msp430_reg_names[] = {
995 	"PC",  "SP",  "SR",  "R3",
996 	"R4",  "R5",  "R6",  "R7",
997 	"R8",  "R9",  "R10", "R11",
998 	"R12", "R13", "R14", "R15"
999 };
1000 
dis_reg_from_name(const char * name)1001 int dis_reg_from_name(const char *name)
1002 {
1003 	int i;
1004 
1005 	if (!strcasecmp(name, "pc"))
1006 		return 0;
1007 	if (!strcasecmp(name, "sp"))
1008 		return 1;
1009 	if (!strcasecmp(name, "sr"))
1010 		return 2;
1011 
1012 	if (toupper(*name) == 'R')
1013 		name++;
1014 
1015 	for (i = 0; name[i]; i++)
1016 		if (!isdigit(name[i]))
1017 			return -1;
1018 
1019 	i = atoi(name);
1020 	if (i < 0 || i > 15)
1021 		return -1;
1022 
1023 	return i;
1024 }
1025 
dis_reg_name(msp430_reg_t reg)1026 const char *dis_reg_name(msp430_reg_t reg)
1027 {
1028 	if (reg <= 15)
1029 		return msp430_reg_names[reg];
1030 
1031 	return NULL;
1032 }
1033