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