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 #ifndef DIS_H_
20 
21 #include <stdint.h>
22 #include "util.h"
23 
24 /* Addressing modes.
25  *
26  * Addressing modes are not determined solely by the address mode bits
27  * in an instruction. Rather, those bits specify one of four possible
28  * modes (REGISTER, INDEXED, INDIRECT and INDIRECT_INC). Using some of
29  * these modes in conjunction with special registers like PC or the
30  * constant generator registers results in extra modes. For example, the
31  * following code, written using INDIRECT_INC on PC:
32  *
33  *     MOV      @PC+, R5
34  *     .word    0x5729
35  *
36  * can also be written as an instruction using IMMEDIATE addressing:
37  *
38  *     MOV      #0x5729, R5
39  */
40 typedef enum {
41 	MSP430_AMODE_REGISTER           = 0x0,
42 	MSP430_AMODE_INDEXED            = 0x1,
43 	MSP430_AMODE_SYMBOLIC           = 0x81,
44 	MSP430_AMODE_ABSOLUTE           = 0x82,
45 	MSP430_AMODE_INDIRECT           = 0x2,
46 	MSP430_AMODE_INDIRECT_INC       = 0x3,
47 	MSP430_AMODE_IMMEDIATE          = 0x83
48 } msp430_amode_t;
49 
50 /* MSP430 registers.
51  *
52  * These are divided into:
53  *
54  *     PC/R0:    program counter
55  *     SP/R1:    stack pointer
56  *     SR/R2:    status register/constant generator 1
57  *     R3:       constant generator 2
58  *     R4-R15:   general purpose registers
59  */
60 typedef enum {
61 	MSP430_REG_PC           = 0,
62 	MSP430_REG_SP           = 1,
63 	MSP430_REG_SR           = 2,
64 	MSP430_REG_R3           = 3,
65 	MSP430_REG_R4           = 4,
66 	MSP430_REG_R5           = 5,
67 	MSP430_REG_R6           = 6,
68 	MSP430_REG_R7           = 7,
69 	MSP430_REG_R8           = 8,
70 	MSP430_REG_R9           = 9,
71 	MSP430_REG_R10          = 10,
72 	MSP430_REG_R11          = 11,
73 	MSP430_REG_R12          = 12,
74 	MSP430_REG_R13          = 13,
75 	MSP430_REG_R14          = 14,
76 	MSP430_REG_R15          = 15,
77 } msp430_reg_t;
78 
79 /* Status register bits. */
80 #define MSP430_SR_V             0x0100
81 #define MSP430_SR_SCG1          0x0080
82 #define MSP430_SR_SCG0          0x0040
83 #define MSP430_SR_OSCOFF        0x0020
84 #define MSP430_SR_CPUOFF        0x0010
85 #define MSP430_SR_GIE           0x0008
86 #define MSP430_SR_N             0x0004
87 #define MSP430_SR_Z             0x0002
88 #define MSP430_SR_C             0x0001
89 
90 /* MSP430 instruction formats.
91  *
92  * NOARG is not an actual instruction format recognised by the CPU.
93  * It is used only for emulated instructions.
94  */
95 typedef enum {
96 	MSP430_ITYPE_NOARG,
97 	MSP430_ITYPE_JUMP,
98 	MSP430_ITYPE_DOUBLE,
99 	MSP430_ITYPE_SINGLE
100 } msp430_itype_t;
101 
102 /* MSP430(X) data sizes.
103  *
104  * An address-word is a 20-bit value. When stored in memory, they are
105  * stored as two 16-bit words in the following order:
106  *
107  *    data[15:0], {12'b0, data[19:16]}
108  */
109 typedef enum {
110 	MSP430_DSIZE_WORD    = 0,
111 	MSP430_DSIZE_BYTE    = 1,
112 	MSP430_DSIZE_UNKNOWN = 2,
113 	MSP430_DSIZE_AWORD   = 3,
114 } msp430_dsize_t;
115 
116 /* MSP430 operations.
117  *
118  * Some of these are emulated instructions. Emulated instructions are
119  * alternate mnemonics for combinations of some real opcodes with
120  * common operand values. For example, the following real instruction:
121  *
122  *    MOV   #0, R8
123  *
124  * can be written as the following emulated instruction:
125  *
126  *    CLR   R8
127  */
128 typedef enum {
129 	/* Single operand */
130 	MSP430_OP_RRC           = 0x1000,
131 	MSP430_OP_SWPB          = 0x1080,
132 	MSP430_OP_RRA           = 0x1100,
133 	MSP430_OP_SXT           = 0x1180,
134 	MSP430_OP_PUSH          = 0x1200,
135 	MSP430_OP_CALL          = 0x1280,
136 	MSP430_OP_RETI          = 0x1300,
137 
138 	/* Jump */
139 	MSP430_OP_JNZ           = 0x2000,
140 	MSP430_OP_JZ            = 0x2400,
141 	MSP430_OP_JNC           = 0x2800,
142 	MSP430_OP_JC            = 0x2C00,
143 	MSP430_OP_JN            = 0x3000,
144 	MSP430_OP_JGE           = 0x3400,
145 	MSP430_OP_JL            = 0x3800,
146 	MSP430_OP_JMP           = 0x3C00,
147 
148 	/* Double operand */
149 	MSP430_OP_MOV           = 0x4000,
150 	MSP430_OP_ADD           = 0x5000,
151 	MSP430_OP_ADDC          = 0x6000,
152 	MSP430_OP_SUBC          = 0x7000,
153 	MSP430_OP_SUB           = 0x8000,
154 	MSP430_OP_CMP           = 0x9000,
155 	MSP430_OP_DADD          = 0xA000,
156 	MSP430_OP_BIT           = 0xB000,
157 	MSP430_OP_BIC           = 0xC000,
158 	MSP430_OP_BIS           = 0xD000,
159 	MSP430_OP_XOR           = 0xE000,
160 	MSP430_OP_AND           = 0xF000,
161 
162 	/* Emulated instructions */
163 	MSP430_OP_ADC           = 0x10000,
164 	MSP430_OP_BR            = 0x10001,
165 	MSP430_OP_CLR           = 0x10002,
166 	MSP430_OP_CLRC          = 0x10003,
167 	MSP430_OP_CLRN          = 0x10004,
168 	MSP430_OP_CLRZ          = 0x10005,
169 	MSP430_OP_DADC          = 0x10006,
170 	MSP430_OP_DEC           = 0x10007,
171 	MSP430_OP_DECD          = 0x10008,
172 	MSP430_OP_DINT          = 0x10009,
173 	MSP430_OP_EINT          = 0x1000A,
174 	MSP430_OP_INC           = 0x1000B,
175 	MSP430_OP_INCD          = 0x1000C,
176 	MSP430_OP_INV           = 0x1000D,
177 	MSP430_OP_NOP           = 0x1000E,
178 	MSP430_OP_POP           = 0x1000F,
179 	MSP430_OP_RET           = 0x10010,
180 	MSP430_OP_RLA           = 0x10011,
181 	MSP430_OP_RLC           = 0x10012,
182 	MSP430_OP_SBC           = 0x10013,
183 	MSP430_OP_SETC          = 0x10014,
184 	MSP430_OP_SETN          = 0x10015,
185 	MSP430_OP_SETZ          = 0x10016,
186 	MSP430_OP_TST           = 0x10017,
187 
188 	/* MSP430X single operand (extension word) */
189 	MSP430_OP_RRCX          = 0x21000,
190 	MSP430_OP_RRUX          = 0x21001, /* note: ZC = 1 */
191 	MSP430_OP_SWPBX         = 0x21080,
192 	MSP430_OP_RRAX          = 0x21100,
193 	MSP430_OP_SXTX          = 0x21180,
194 	MSP430_OP_PUSHX         = 0x21200,
195 
196 	/* MSP430X double operand (extension word) */
197 	MSP430_OP_MOVX          = 0x24000,
198 	MSP430_OP_ADDX          = 0x25000,
199 	MSP430_OP_ADDCX         = 0x26000,
200 	MSP430_OP_SUBCX         = 0x27000,
201 	MSP430_OP_SUBX          = 0x28000,
202 	MSP430_OP_CMPX          = 0x29000,
203 	MSP430_OP_DADDX         = 0x2A000,
204 	MSP430_OP_BITX          = 0x2B000,
205 	MSP430_OP_BICX          = 0x2C000,
206 	MSP430_OP_BISX          = 0x2D000,
207 	MSP430_OP_XORX          = 0x2E000,
208 	MSP430_OP_ANDX          = 0x2F000,
209 
210 	/* MSP430X group 13xx */
211 	MSP430_OP_CALLA         = 0x21300,
212 
213 	/* MSP430X group 14xx */
214 	MSP430_OP_PUSHM         = 0x1400,
215 	MSP430_OP_POPM		= 0x1600,
216 
217 	/* MSP430X address instructions */
218 	MSP430_OP_MOVA          = 0x0000,
219 	MSP430_OP_CMPA          = 0x0090,
220 	MSP430_OP_ADDA          = 0x00A0,
221 	MSP430_OP_SUBA          = 0x00B0,
222 
223 	/* MSP430X group 00xx, non-address */
224 	MSP430_OP_RRCM		= 0x0040,
225 	MSP430_OP_RRAM		= 0x0140,
226 	MSP430_OP_RLAM		= 0x0240,
227 	MSP430_OP_RRUM		= 0x0340,
228 
229 	/* MSP430X emulated instructions */
230 	MSP430_OP_ADCX		= 0x40000,
231 	MSP430_OP_BRA		= 0x40001,
232 	MSP430_OP_RETA		= 0x40002,
233 	MSP430_OP_CLRX		= 0x40003,
234 	MSP430_OP_DADCX         = 0x40004,
235 	MSP430_OP_DECX		= 0x40005,
236 	MSP430_OP_DECDA		= 0x40006,
237 	MSP430_OP_DECDX		= 0x40007,
238 	MSP430_OP_INCX		= 0x40008,
239 	MSP430_OP_INCDA		= 0x40009,
240 	MSP430_OP_INVX		= 0x4000A,
241 	MSP430_OP_RLAX		= 0x4000B,
242 	MSP430_OP_RLCX		= 0x4000C,
243 	MSP430_OP_SECX		= 0x4000D,
244 	MSP430_OP_TSTA		= 0x4000E,
245 	MSP430_OP_TSTX		= 0x4000F,
246 	MSP430_OP_POPX		= 0x40010,
247 	MSP430_OP_INCDX		= 0x40011,
248 } msp430_op_t;
249 
250 /* This represents a decoded instruction. All decoded addresses are
251  * absolute or register-indexed, depending on the addressing mode.
252  *
253  * For jump instructions, the target address is stored in dst_operand.
254  */
255 struct msp430_instruction {
256 	address_t               offset;
257 	int                     len;
258 
259 	msp430_op_t             op;
260 	msp430_itype_t          itype;
261 	msp430_dsize_t          dsize;
262 
263 	msp430_amode_t          src_mode;
264 	address_t               src_addr;
265 	msp430_reg_t            src_reg;
266 
267 	msp430_amode_t          dst_mode;
268 	address_t		dst_addr;
269 	msp430_reg_t            dst_reg;
270 
271 	int			rep_index;
272 	int			rep_register;
273 };
274 
275 /* Decode a single instruction.
276  *
277  * Returns the number of bytes consumed, or -1 if an error occured.
278  *
279  * The caller needs to pass a pointer to the bytes to be decoded, the
280  * virtual offset of those bytes, and the maximum number available. If
281  * successful, the decoded instruction is written into the structure
282  * pointed to by insn.
283  */
284 int dis_decode(const uint8_t *code,
285 	       address_t offset, address_t len,
286 	       struct msp430_instruction *insn);
287 
288 /* Look up names for registers and opcodes */
289 int dis_opcode_from_name(const char *name);
290 const char *dis_opcode_name(msp430_op_t op);
291 int dis_reg_from_name(const char *name);
292 const char *dis_reg_name(msp430_reg_t reg);
293 
294 #endif
295