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